【问题标题】:Calling State Altering Reducer Functions Sequentially in Redux在 Redux 中按顺序调用 State Altering Reducer 函数
【发布时间】:2016-08-19 02:06:19
【问题描述】:

我正在学习 Redux,并且遇到了与确保状态树的分支(分支 A)在我更新另一个分支(分支 B)之前完成更新有关的问题。分支 B 依赖于分配给分支 A 中新更新项目的 ID,因此我希望分支 B 的更新函数在更新分支 A 的调度函数完成后调度。我有多个对应于各个分支的减速器,我正在使用 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,那么一切都会按预期进行。在这种情况下,状态更新已完成,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,但我不确定其中哪一个是解决这个问题的合适工具,或者它们中的任何一个是否是合适的工具.解决此类问题的正确方法是什么?

【问题讨论】:

    标签: redux


    【解决方案1】:

    这里的问题是,您从中分派这些操作的组件内的 criteria 属性没有机会更新。但是,状态原子本身内部的标准值已经更新。请允许我进一步解释。

    我们称这行代码为Line 1this.props.dispatch(actions.addCriterion(this.state));

    我们将这行代码称为Line 2this.props.dispatch(actions.completeScoreGrid(this.props.alternatives, this.props.criteria));

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

    那么你如何解决这个问题?有几种方法,但这是我最好的建议。除了将this.props.criteria 传递给completeScoreGrid 动作创建者之外,您还可以使用redux-thunk 来启用异步动作,并从异步动作创建者内部的redux 状态原子中获取条件。假设条件存储在state.criteria,那么异步操作创建者的外观如下。

    function completeScoreGrid(alternatives) {
      return (dispatch, getState) => {
        const state = getState();
        const criteria = state.criteria;
        dispatch({
          type: 'COMPLETE_SCORE_GRID',
          payload: {
            criteria,
            alternatives
          }
        });
      }
    }
    

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

    【讨论】:

      【解决方案2】:

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

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

      Link to Reddit post on this question

      你能发布你的减速器是什么样子的吗?新状态不会反映在第二次调用中,这听起来不对。 但是,当您说分支 B 依赖于分配给分支 A 中的新项目的 ID 时……您是在减速器还是在动作创建器中生成此 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.
      

      【讨论】:

        猜你喜欢
        • 2016-01-29
        • 1970-01-01
        • 2017-08-12
        • 1970-01-01
        • 1970-01-01
        • 2012-01-07
        • 1970-01-01
        • 1970-01-01
        • 2022-01-12
        相关资源
        最近更新 更多