中间件中的调度方法不触发减速器

Dispatch method in middleware not triggering reducer

使用Redux Thunk中间件提供的参数中的store方法dispatch不会触发reducer。使用 next() 可以正常工作,因为它会触发减速器。为什么会这样?

中间件

export default function createSlimAsyncMiddleware({
    dispatch,
    getState
}) {
    return next => action => {
    const {
        types,
        callAPI,
        shouldCallAPI = () => true,
    } = action;
    if (!actionIsValid(action)) next(action);
    if (shouldCallAPI(getState())) {
        return Promise.resolve(getState());
    }
    const [pendingType, successType, errorType] = types;
    dispatch({
        type: pendingType
    });
    return callAPI()
        .then(response => {
            dispatch({  // Does not work, use next()
                type: successType,
                payload: response,
            });
            console.log('call resolved with type', successType)
            return Promise.resolve(getState());
        })
        .catch(error => {
            dispatch({  // Does not work, use next()
                type: errorType,
                payload: error,
            });
            return Promise.reject(error);
        });
    };
}

商店

const store = createStore(
    appReducer,
    composeWithDevTools(applyMiddleware(
    thunk,
    createSlimAsyncMiddleware,
    routerMiddleware(history)
    ))
)

关于此回复 dispatch 也应该有效。

这在您包含的链接响应中有说明,但调用 dispatch() 将创建一个新操作,然后从头开始遍历整个中间件链。在您的情况下,这包括您正在排除故障的中间件。据我所知,您唯一一次调用 next() 是在传入操作被视为无效的情况下。否则,后续的 API 调用会导致 dispatch() 被再次调用,无论调用成功还是失败,因此该操作永远不会到达 reducer,因为它一直在中间件链的开头设置并且永远不会通过 next().

继续前进

当您说此代码不起作用时,具体行为是什么?您的应用挂起了吗?它会崩溃吗?因为此场景实质上设置了一个没有基本情况的递归函数,所以我敢打赌您会看到 'maximum call stack exceeded' 类错误。

我想我会问为什么您需要使用 dispatch() 作为请求结果而不是使用 next() 发送它们,或者为什么您没有以这样的方式进行设置设置一个条件,使用上一次调用的结果来确定 API 是否再次被调用。