2016-08-19 72 views
0

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

我用下面的派遣行动从组件更新分公司答:

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

按顺序调度上的代码产生分行A没有看到更新的状态信息的下一行更新分公司B中的作用由分公司A派遣引起。

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

然而,一切正常,如果我使用setTimeout和等待一个有点后分派调用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,我不确定哪些是用于解决这个问题的正确工具,或者它们是否是适当的工具。解决这类问题的正确方法是什么?

回答

0

我最终使用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. 
1

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

让我们把下面这行代码Line 1this.props.dispatch(actions.addCriterion(this.state));

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

Line 1后已经完成,在终极版状态原子criteria包括新的标准。但是,Line 2中的criteria prop尚未刷新,因为React尚未更新组件以响应redux状态更改。

那么你如何解决这个问题呢?有几种方法,但这是我最好的建议。您可以使用redux-thunk启用异步操作,并从异步操作创建者内部的redux状态原子中获取标准,而不是将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以响应此操作。如果您有任何问题,请告诉我。