在 componentWillUnmount 中到底應該清除哪些變數?

官方文檔中提到需要清除的是 timer,networking,以及在 componentDidMount 中聲明的變數。

1 通常我聲明一個變數的時候都是通過 this.foo 來做的,以在不同的生命周期中共享。這種做法是正確的嗎?

2 那麼當一個組件 unmount 的時候,這個組件即將銷毀,按我的理解,它的 this 值也會一併被銷毀,所以即使在 componentDidMount 中聲明了一個 this.foo = setInterval(),或者一些初始值 this.foo = ReactDOM.findDOMNode(ref.foo),它們也會隨同組件銷毀,因此在 componentWillUnmount 中將這些值 clearInterval 或 this.foo = null 是沒必要的?可是官方文檔中使用了 clearInterval,我的理解是錯誤的嗎?

3 為什麼官方文檔僅僅說在 componentDidMount 中聲明的才需要清除?為什麼 componentWillMount 或者在其他任意生命周期內創建的變數不需要清除?


謝邀。

  1. 正確,但是這種成員變數的修改不會直接引發組件更新,需要引發組件更新的數據應該放在this.state中。
  2. unmount只是把組件從界面中拿掉,組件的實例並沒有銷毀,即使組件銷毀了,它所佔用的對象不用處理,this.foo = null 沒必要,但是clearInterval有必要。
  3. 佔用的資源都該被釋放,只是分配這些資源通常放在componentDidMount里而已。


setInterval返回的是id,在調用後會不斷執行。直到被clearInterval傳入對應id後清除。

所以當組件被銷毀的時候,被回收的是id的變數。不是計時器。計時器本身並沒有綁定在組件上,所以會繼續執行。

你可以console.log看看setInterval返回的是什麼。

而didMount和willMount區別在於,will中會同時在服務端和客戶端執行。而服務端渲染是同步的,如果在服務端做了非同步調用,那麼會出現setState warning。而did只會在客戶端執行,客戶端允許出現非同步,所以在did中申明的非同步行為你可以在willUnmount里清除。


如果使用了setInterval和addEventListener,往往會涉及到this.setState方法,組件銷毀後如果這兩方法繼續執行就會報錯。需要在componentWillUnmount周期移除,即clearInterval 和 removeEventListener。


考慮一個 slider 或者類似的,他會在 didmount 的時候 document.addEventListener 來動態獲得大小以及處理一些萬一滑鼠移除邊界的活動。在 umount 的時候最好把這些 listener 移除

所以當你寫 react 的時候常常不幸地要寫 raw dom,以及部分插件真難跨平台


推薦閱讀:

store的組織是扁平化好,還是分層級樹狀的好?大型的項目store該怎麼組織?
新手學習前端開發加了很多技術群有必要天天看群聊天記錄學習嗎?
截止到2017年7月,手淘內部還在用vue嗎,有替換成react嗎?

TAG:JavaScript | GC垃圾回收計算機科學 | React |