Redux传奇击中减速器后无法捕获动作

时间:2019-12-09 21:02:24

标签: redux-saga

我正在尝试为客户端实现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)])
    }

没有错误,因为这是一个逻辑问题,而不是句法问题

2 个答案:

答案 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)
}

然后减速器将进行相应的更新

祝你好运