2017-04-11 153 views
0

我手動將React組件掛接到Redux存儲。是的,我意識到Redux的Dan Abramov recommends against this。我最終會考慮採用react-redux,但現在我想知道發生了什麼。Redux在componentWillUnmount中取消訂閱仍然調用訂閱回調

componentDidMount() { 
    this.unsubscribe = store.subscribe(() => { 
     const storeState = store.getState(); 
     this.setState({ 
      someData: storeState.someData 
     }); 
    }.bind(this)); 
} 
componentWillUnmount() { 
    this.unsubscribe(); 
} 

這是我在標籤頁組件中的一些代碼。當用戶改變標籤以顯示不同的數據時,這些標籤頁被交換進父組件中。我已經通過調試器階梯和確認,隨着用戶改變的選項卡,以下爲了發生:

  1. 前一標籤被卸載(componentWillUnmount火災和this.unsubscribe()稱爲this是先前的選項卡組件,如所預期。)
  2. 新選項卡已安裝。 (componentDidMount火災和this是新的標籤組件,如預期)
  3. setState被調用的訂閱回調與this是前一個標籤,並作出反應有一個錯誤抱怨:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the Tab component.

這似乎很奇怪對我來說。不應該調用unsubscribe,因爲我阻止在未掛載組件上調用此回調函數? post that I'm following along with似乎表明,做我所做的事情應該讓這個警告消失,並且只是在質疑這是否是一個好主意。但就我而言,它仍然存在。

我不認爲它很重要,但我使用ES6「類」的語法,而原來的似乎不是。

回答

2
subscribe(listener:() => void): Unsubscribe; 

讓我們閱讀訂閱方法doc。

  1. The subscriptions are snapshotted just before every dispatch() call. If you subscribe or unsubscribe while the listeners are being invoked, this will not have any effect on the dispatch() that is currently in progress. However, the next dispatch() call, whether nested or not, will use a more recent snapshot of the subscription list.

既然你第一次呼籲調度方法,所有的聽衆都invoken和你unsubsribe通話將只需要在下一調度呼叫的地方。