[英]Redux Thunk + ReactJS: Action creator being called but dispatch function not being called
我遇到了一個我以前從未見過的ReactJS x Redux應用程序的一個相當奇怪的問題,並且很難搞清楚。
在我的ReactJS組件中,我正在連接一個動作創建器函數,該函數使用redux-thunk
進行異步調用,然后使用來自react-redux
+對象mapDispatchToProps
表示法的connect()
函數調度到reducer。 它看起來像這樣:
const mapStateToProps = (state) => ({
...state.single_pano
});
const mapDispatchToProps = {
loadPano
};
export default connect(mapStateToProps, mapDispatchToProps)(PanoView);
為簡單起見,讓我們說loadPano
動作創建者看起來像這樣:
export const loadPano = (id) => {
console.log('Action creator called.');
return async (dispatch) => {
console.log('Dispatch function called.');
const doc = await db.doc('/path/to/doc/'+id).get();
dispatch({
type: 'LOAD_ACTION',
payload: doc
});
}
}
事情變得奇怪:
在我的componentDidMount()
生命周期函數中,我正在調用this.props.loadPano(panoID)
,它完全按預期工作(調用action creator中的console.log()
調用, async
/ await
返回和動作被發送到reducer)。
稍后,我需要在組件的componentWillReceiveProps()
生命周期函數中再次調用this.props.loadPano(panoID)
,因為URL參數已更改,並且需要獲取並重新加載某些數據。 但是,這次最終發生的是調用動作創建器( loadPano
),但是loadPano
調用redux-thunk
調度函數( return (dispatch) => { ... }
)。 我可以告訴這種情況,因為第一個console.log()
被調用,但第二個從未登錄到控制台。
我正在做的其他一些與我有關的事情可能是相關的,但到目前為止,我一直無法確認其中任何一個:
PanoView
組件使用shouldComponentUpdate()
生命周期方法來控制何時呈現DOM。 PanoView
組件狀態之外的變量來存儲第三方庫對象,該對象通過DOM ref
直接修改DOM,並且無法正確使用ReactJS。 但是我相信這是孤立的,並且看不出它會如何干擾Redux / Thunk。 特別是因為調度功能第一次正確觸發。 相關依賴項+版本(通過yarn
安裝):
"firebase": "^5.2.0",
"photo-sphere-viewer": "^3.4.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-redux": "^5.0.7",
"react-router-dom": "^4.3.1",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
請求的更新:
我的用於PanoView
組件的componentWillReceiveProps
lifecylce函數如下所示:
componentWillReceiveProps(newProps) {
// Pano received
const oldPanoID = this.props.match.params.panoID;
const newPanoID = newProps.match.params.panoID;
if (oldPanoID !== newPanoID) {
loadPano(newPanoID);
}
}
當我們對您的代碼一無所知時,很難(幾乎不可能)猜出問題所在。 你的componentWillReceiveProps
是怎樣的?
這是一個可能導致混淆的好習慣:
const mapDispatchToProps = {
loadPano
};
Redux thunk本質上是一個中間件,可以檢查每個調度的動作。 如果動作返回一個函數,則它調用該函數,然后將dispatch
和state
參數傳遞給返回的函數,然后它也調用該函數。
所以我的猜測是:
componendDidMount
您調用this.props.loadPano(id)
componentWillReceiveProps
您只調用loadPano
。 第一個是store.dispatch(loadPano)
並進入reducer。 第二個只是loadPano
並返回一個promise。 (你的行動創造者)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.