我正在尝试为客户端实现redux saga,但是在遇到reducer之后我无法得到saga来捕获动作。我的传奇故事似乎从来没有触发过,因此在我调用“ DATA_FETCH_REQUESTED”减速器动作后,我没有达到我的期望。
我期望的结果是:对于我的传奇,我的redux存储中的errorMessage变量包含获取的数据,或者如果获取失败,则显示错误消息。
我得到的结果是:我的传奇未触发,并且我的redux存储中的errorMessage变量始终以字符串“ ###传奇未能捕获此动作###”结尾(应该但应该然后由我的传奇动作纠正,这种动作永远不会发生
我在这里担心的是,传奇的中间件永远无法正常启动。我已经将打印语句放到我的传奇中,但我从未在控制台中看到它们,这似乎证实了我的理论。任何帮助将不胜感激。参见下面的代码:
这是我的根传奇文件:
function fetchData() {
// fetches data
}
function* callFetchData() {
try {
const data = yield call(fetchData)
yield put({ type: "DATA_FETCH_SUCCEEDED", data: data })
} catch (e) {
yield put({ type: "DATA_FETCH_FAILED", message: e.message })
}
}
function* fetchDataSaga() {
yield* takeEvery("DATA_FETCH_REQUESTED", callFetchData)
}
function* rootSaga() {
yield [fork(fetchDataSaga)]
}
export default rootSaga
这是我的减速器:
const initialState = {
errorMessage: null,
}
const dataReducer = (state = initialState, { payload, type }) => {
switch (type) {
case "DATA_FETCH_REQUESTED": {
return {
...state,
errorMessage: '### saga failed to catch this action ###',
}
}
case "DATA_FETCH_SUCCEEDED": {
return {
...state,
errorMessage: payload.data,
}
}
case "DATA_FETCH_FAILED": {
return {
...state,
errorMessage: payload.errorMessage,
}
}
default: {
return state
}
}
}
export default dataReducer
这是我的index.js文件:
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { Provider } from 'react-redux'
import rootReducer from './redux/rootReducer'
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import rootSaga from './sagas/rootSaga'
const sagaMiddleware = createSagaMiddleware()
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware))
sagaMiddleware.run(rootSaga)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
更新:
似乎我只是忘了将rootSaga的yielded值包装在“ redux-saga / effects”库的all()方法中。将其更改为以下内容:
function* rootSaga() {
yield all([fork(fetchDataSaga)])
}
没有错误,因为这是一个逻辑问题,而不是句法问题
答案 0 :(得分:1)
击中减速器之前,我无法理解传奇故事。
Redux传奇无法做到。 Redux传奇的目的是先将动作发送给reducer,然后再发送给sagas。
如果由于某种原因您需要先由一个传奇来处理一个动作,那么我建议将其分为两个动作:第一个动作不被任何化简器监听,因此即使它归化简器也可以没有效果。然后,传奇故事得到了它,它转身并分派了第二个动作。第二个动作是减速器处理的动作。
答案 1 :(得分:0)
您的DATA_FETCH_REQUESTED
动作在哪里?看来您希望传奇能听到您的减速器。减速器是此流中的最终目的地,因此不会触发任何操作,而只会更新其状态。
正确的流程应如下所示:
您需要在代码中调用一个动作,以发送获取数据的请求
// Action: to be called from within your component
export function fetchData() {
return { type: "DATA_FETCH_REQUESTED" };
}
然后,传奇故事一旦识别出DATA_FETCH_REQUESTED
动作就将执行
// Saga: handles DATA_FETCH_REQUESTED action call
function* callFetchData() {
try {
const wizards = yield call(fetchData) // <--- did you mean data instead of wizards?
yield put({ type: "DATA_FETCH_SUCCEEDED", data: data })
} catch (e) {
yield put({ type: "DATA_FETCH_FAILED", message: e.message })
}
}
// Saga: listen to DATA_FETCH_REQUESTED actions
function* fetchDataSaga() {
yield* takeEvery("DATA_FETCH_REQUESTED", callFetchData)
}
然后减速器将进行相应的更新
祝你好运