2017-04-11 157 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通话将只需要在下一调度呼叫的地方。