2016-06-29 33 views
7

能有人給我如何做反應,終極版以下線索:如何應對redux中的狀態變化併發出另一個動作?

A組分調度,更新狀態(異步)的動作

成分B(不是A的一個子組件)需要能夠檢測狀態何時發生變化併發送另一個動作。

我的問題是當我嘗試在組件B中執行調度操作2時,狀態仍處於初始狀態並且未更新。

我也試過在componentWillUpdate調度動作2,但是,創建一個無限循環,因爲第二個動作也更新狀態(和異步)

這是怎麼樣子,或多或少:

//----- Component A 
class ComponentA extends React.Component { 
    constructor(props) { 
    super(props); 
    this.props.dispatch(loadEvents()); // loadEvents is async and will update state.eventsState 
    } 
} 

const mapStateToProps = function (state) { 
    return { 
    eventsState: state.eventsState, 
    }; 
}; 

export default connect(mapStateToProps)(ComponentA); 


//----- Component B 
class ComponentA extends React.Component { 
    constructor(props) { 
    super(props); 
    props.dispatch(getEventUsers(props.eventsState.eventId)); // the eventsState is in initial state here (empty)...where do I call getEventUsers? 
    } 

    componentWillUpdate(nextProps) { 
    nextProps.dispatch(getEventUsers(props.eventsState.eventId)) // Creates an infinite loop, getEventUsers also updates state 
    } 
} 

const mapStateToProps = function (state) { 
    return { 
    eventsState: state.eventsState, 
    }; 
}; 

export default connect(mapStateToProps)(ComponentA); 
+0

組件B應該考慮啓動負載和負載之間的時間。它可以顯示一個微調或沒有(空格)。即使你的'loadEvents' reducer是同步的,也不能保證它首先被調度。 React獨自決定何時調用各種函數,比如'shouldComponentUpdate'甚至你的組件構造函數。 – DDS

回答

2

不看你的終極版的代碼,我會說你的成分B的構造,因爲它是在大約同一時間的成分A實例化越來越空的數據,並在該點的異步請求,由組件A發起構造函數仍在進行中。

當異步請求完成時,您的Redux應該觸發包含接收數據的操作。然後你的reducer將這些數據置於狀態,這反過來改變了連接組件的道具並迫使它們放棄。

只有當props.eventState.eventId存在並已更改時,才應該派發getEventUsers。

+0

這很有道理,謝謝!你將如何檢查props.eventState.eventId是否存在?我應該將nextProps與componentWillUpdate中的this.props進行比較嗎? – mvovchak

+1

將this.props與nextProps進行比較的問題在於,如果您的eventUsers包含在eventState中,則在加載用戶時您將獲得新的eventState引用,因此即使事件相同,它們也會不同,從而導致eventUsers再次被提取。比較id可以確保你真的在尋找不同的事件。如果您想在某個時間點重新加載相同事件的數據,則可能會出現問題。我建議你的狀態正常化:將所有加載的用戶保存在一個單獨的對象中,將他們的ID映射到用戶數據,然後在事件對象中通過ID引用它們。 –

相關問題