在 mapDispatchToProps 中使用 thunk

Using thunks in mapDispatchToProps

我想知道如何在 mapDispatchToProps 中为 react-reduxconnect 使用异步动作创建器。我正在使用 redux-thunk 中间件,以下是我的 mapDispatchToProps:

function mapDispatchToProps(dispatch) {
    return {
        foo: function() {
            dispatch(someAction());

            return function asyncAction(dispatch, getState) {
                console.log("An async action!");
                dispatch(someOtherAction(getState().foo));
            };
        }
    }
}

但是,当我执行上述操作时,异步操作不会执行。正确的做法是什么?

我建议以不同的方式声明您的实际 thunk (someOtherAction)。在下面的示例中,asyncAction 是一个异步操作创建者,returns 是一个 thunk。然后 thunk 可以调度其他操作(例如,在承诺解决之后)。

function asyncActionCreator () {
  return (dispatch, getState) => {
    dispatch(someAction());

    someAsyncStuff().then(() => {
      dispatch(someOtherAction(getState().foo);
    });
  }
}

function mapDispatchToProps(dispatch) {
  return {
    foo: () => dispatch(asyncActionCreator())
  }
}

为了完整起见,我要添加这个。 我需要使用 1 个动作创建者来分派 2 个动作,但第二个动作取决于第一个动作的结果。第二个操作还需要访问存储的不同部分,因此我不能使用我用来设置第一个值的同一个 reducer。

我的 mapDispatchToProps,使用 redux-thunk,最终看起来如下:

import constants from '../constants';

const mapDispatchToProps = (dispatch) => {
    return {
        setValuesToStore: (value) => {
            const firstAction = {
                type: constants.SET_FIRST_VALUE,
                value,
            }
            dispatch(firstAction)
            dispatch(secondAction())
            function secondAction() {
                return (dispatch, getState) => {
                    const state = getState()
                    dispatch({
                        type: constants.SET_SECOND_VALUE,
                        state,
                    })
                }
            }
        }
    }
}

这样我就不需要将商店作为模块导入,我觉得这很丑陋。没什么大不了的,只是希望这会有所帮助。

尽管接受的答案显然更可取,但我相信对您的代码的这个小修改也可能有助于理解此机制的工作原理:

function mapDispatchToProps(dispatch) {
    return {
        foo: () => dispatch(function() { // <-- Note the dispatch!
            dispatch(someAction());

            return function asyncAction(dispatch, getState) {
                console.log("An async action!");
                dispatch(someOtherAction(getState().foo));
            };
        }()) // <-- Note the IIFE!
    }
}

你原来的 thunk 创建函数(与 foo 相关)实际上必须是 immediately invokeddispatch,这个模式才能工作。