调用状态在Redux中按顺序改变Reducer函数

时间:2016-08-19 02:06:20

标签: redux

我正在学习Redux,并且在更新另一个分支(分支B)之前遇到了与确保我的状态树的分支(分支A)已完成更新有关的问题。分支B依赖于分配给分支A中新更新项目的ID,因此我希望分支B的更新功能在更新分支A的分派功能完成后进行分派。我有多个与各个分支对应的reducer,我使用combineReducers来组合它们。

我使用以下命令从组件中分派更新分支A的操作:

/* update Branch A */
this.props.dispatch(actions.addCriterion(this.state));

按顺序调度在下一行代码上更新分支B的操作会导致分支B看不到分支A分派导致的更新状态信息。

/* update Branch B */
this.props.dispatch(actions.completeScoreGrid(this.props.alternatives, this.props.criteria));

但是,如果我使用setTimeout并在调用A之后等待一段时间后,一切都按预期工作。在这种情况下,状态更新完成,B看到它应该的一切

/* update Branch B after a 1 second pause */    
    var that = this;
    setTimeout(function() {
        that.props.dispatch(actions.completeScoreGrid(that.props.alternatives, 
    that.props.criteria));
    }, 1000);

但是,我确定使用设置超时不是正确的方法。我看起来像redux-thunk,redux-promise,redux-promise-middleware和redux-saga,我不确定哪个是适合这个问题的工具,或者它们中的任何一个是否是正确的工具。解决这类问题的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

这里的问题是,您从中发送这些操作的组件中的criteria prop没有机会更新。但是,state atom本身内部的条件值已经更新。请允许我进一步解释。

让我们调用这行代码Line 1this.props.dispatch(actions.addCriterion(this.state));

让我们调用这行代码Line 2this.props.dispatch(actions.completeScoreGrid(this.props.alternatives, this.props.criteria));

Line 1完成后,redux state atom中的criteria包含新标准。但是,criteria中的Line 2道具尚未刷新,因为React尚未更新组件以响应redux状态更改。

那你怎么解决这个问题呢?有几种方法,但这是我最好的建议。您可以使用redux-thunk启用异步操作,并从异步操作创建器中的redux state atom获取条件,而不是将this.props.criteria传递给completeScoreGrid动作创建者。假设条件存储在state.criteria

,这就是异步操作创建者的外观
function completeScoreGrid(alternatives) {
  return (dispatch, getState) => {
    const state = getState();
    const criteria = state.criteria;
    dispatch({
      type: 'COMPLETE_SCORE_GRID',
      payload: {
        criteria,
        alternatives
      }
    });
  }
}

然后,您可以更新分支B以响应此操作。如果您有任何问题,请告诉我。

答案 1 :(得分:0)

我最终使用thunk-redux来解决问题,并将Brandon Lewis的帖子标记为上面的答案。

此外,Reddit用户cyex在我的Reddit帖子中发布了另一种技术,询问同样的问题。我测试了它,它也做了我想要完成的事情。我已经链接到下面的帖子,并在此粘贴了他的解决方案。

Link to Reddit post on this question

你能发布你的减速器的样子吗?新状态不会反映在第二次通话中听起来不对。 但是当你说分支B依赖于分配给分支A中的新项目的ID时...你是在reducer中还是在你的动作创建者中生成这个ID? 例如如果你的代码看起来像这样呢?

/* update Branch A */
var newCriterion = actions.addCriterion(this.state); // ID is assigned here, not in reducer
this.props.dispatch(newCriterion);

/* update Branch B */
var scoreGrid = actions.completeScoreGrid(this.props.alternatives, this.props.criteria, newCriterion.id);
this.props.dispatch(scoreGrid);
So the B reducer doesn't need to look at anything on another branch.