2016-08-19 75 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以響應此操作。如果您有任何問題,請告訴我。