簡體   English   中英

Redux Thunk + ReactJS:正在調用動作創建者但未調用調度函數

[英]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。
  • 我是一個小hacky /不是最好的練習 - 使用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本質上是一個中間件,可以檢查每個調度的動作。 如果動作返回一個函數,則它調用該函數,然后將dispatchstate參數傳遞給返回的函數,然后它也調用該函數。

所以我的猜測是:

  1. componendDidMount您調用this.props.loadPano(id)
  2. componentWillReceiveProps您只調用loadPano

第一個是store.dispatch(loadPano)並進入reducer。 第二個只是loadPano並返回一個promise。 (你的行動創造者)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM