【问题标题】:Redux-Thunk Chaining Actions, getting a "dispatch(...) then is not a function errorRedux-Thunk Chaining Actions,得到一个“dispatch(...)然后不是函数错误
【发布时间】:2017-12-27 22:00:51
【问题描述】:

为了让我设置合成,我必须先获取输出对象。
我正在尝试复制示例,我觉得我正在正确复制语法,但我不断收到错误:

未捕获的 TypeError: dispatch(...).then 不是函数

Actions.js

export function setComposition(composition) {
  return { type: types.SET_COMPOSITION, composition };
}

export function setOutputs(outputs) {
  return { type: types.SET_OUTPUTS, outputs };
}

export function setOutputsAndComposition(outputs) {
  return function (dispatch, getState) {
    return dispatch(setOutputs(outputs)).then(() =>  // ERROR HERE
      dispatch(setComposition(getState().Data.OutputObj))
    );
  }
}

编辑:理想情况下,我只想创建一个功能:

export function setOutputsAndComposition(outputs) {
  return function (dispatch, getState) {
    dispatch(setOutputs(outputs)).then(() =>
    dispatch(setComposition(getState().Data.OutputObj))
    );
  }
}

但我显然没有正确地使用语法

【问题讨论】:

    标签: javascript reactjs redux redux-thunk


    【解决方案1】:

    setOutputs() 正在返回一个普通的操作对象,因此不是一个返回承诺的 thunk。所以,链接dispatch(setOutputs(outputs)).then() 是行不通的。

    如果你只是想在setOutputs()调度完成后立即调度另一个动作,你只需要把它们放在一个之后:

    dispatch(setOutputs(outputs));
    dispatch(setComposition(getState().Data.OutputObj));
    

    【讨论】:

    • 如果我想让 ".then()" 工作,我的 setOutputs 函数必须返回什么?
    • 正如我所说,它需要是另一个 thunk 函数,并且需要返回一个承诺。
    • @markerikson:你的意思是 thunk 中的 dispatch 就像 saga 中的 yield 一样。我的观点是,假设如果您希望某个动作在另一个动作之后调度 - 我们需要使用 .then 来确保第一个动作已经返回。
    • 你混淆了两种不同的东西。 thunk 中的 dispatch 参数与 Redux 存储中的 store.dispatch 方法完全相同。 yield 是一个 JS 关键字,用于暂停 saga 并将值传递给迭代器。 Redux-Saga API 允许您使用put() 效果进行调度,例如yield put({type: "increment"})
    • @markerikson :我明白了你的意思,但是当你上面提到当需要调度 2 个动作时,你需要在另一个调度之后立即调度,我想知道第二个调度是否会等待如果第一个调度需要时间返回,则第一个返回并且不开始执行。我有一个用例,我想连续调度 2 个动作,但第二个动作应该在第一个动作返回后才开始,使用 .then 给出错误
    【解决方案2】:

    您可以使用setOutputs() 作为自定义中间件。在这种情况下,我将其用作Promise

    export function setComposition(composition) {
      return { type: types.SET_COMPOSITION, composition };
    }
    
    export function setOutputs(outputs, dispatch) {
      return new Promise((resolve, reject) => {
        dispatch({type: types.SET_OUTPUTS, outputs});
        resolve();
      });
    }
    
    export function setOutputsAndComposition(outputs) {
      return function (dispatch, getState) {
        return setOutputs(outputs, dispatch).then(() =>  // NO ERROR HERE ANYMORE ^_^
          dispatch(setComposition(getState().Data.OutputObj))
        );
      }
    }
    

    【讨论】:

    • 感谢替代方法。检查出来
    • 看来这种方法不可行,会导致另一个错误 - Uncaught Error: Actions must be plain objects. Use custom middleware for async actions. 它建议您必须使用中间件,例如 redux-thunk 进行此类操作
    猜你喜欢
    • 2021-04-26
    • 2017-04-30
    • 2017-06-09
    • 2019-04-08
    • 2017-10-31
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    相关资源
    最近更新 更多