React原始碼分析 - 生命週期

_zon_發表於2018-02-25

React的生命週期函式是平時開發過程中經常會使用到的鉤子函式,需要注意的地方在於:

  1. 生命週期函式被執行的時機。
  2. 這些方法中的setState的使用與否以及產生的效果如何。

生命週期函式在元件初次渲染、元件更新以及元件解除安裝的情況下會被呼叫,沒什麼特別的機制上的特殊的地方,需要注意的就是多層級的元件中的各個元件的生命週期函式的執行會遵循父元件至子元件遞迴的順序,這和元件渲染、更新和解除安裝時的遍歷順序有關係,這裡要注意的是在遞迴點之前被呼叫的函式是遵循 父元件->子元件 的順序;在遞迴點後呼叫的函式是遵循 子元件->父元件 的順序,具體可以看之前的《元件初次渲染》和《元件更新》兩篇文章中的流程圖,生命週期函式就是在這個過程中被執行的,有的生命週期函式會使用事務的方式,按順序蒐集到一個佇列中,在事務結束的時候一併執行,這樣一方面保證了執行的順序另一方面也可以保證函式執行的統一的時機。

引用一張圖來描述如下【圖片來源:React 元件的生命週期】:

image

下面主要總結一些需要注意的點【大部分摘抄自參考資料】,原理不解釋了,原始碼可以很明白的看懂:

  • componentWillMount中呼叫setState是不會觸發re-render的,而是會進行state合併。componentWillMount中的this.state不是最新的,在render中才可以獲得更新之後的this.state。

  • 遞迴點是render方法,因此根據遞迴的特性,父元件的componentWillMount在其子元件的componentWillMount之前呼叫,而父元件的componentDidMount在其子元件的componentDidMount之後呼叫。

  • componentWillReceiveProps中呼叫setState是不會觸發re-render的,而是進行state的合併。。

  • 只有在render和componentDIdUpdate中才能獲取到更新後的this.state。

  • 和mount階段一樣在update階段遞迴點是render,父子元件的 componentWillUpdate -> render-> componentDidUpdate 執行的順序類似mount階段,就不重複了。

  • shouldComponentUpdate和componentWillUpdate中無條件呼叫(沒有額外的判斷是否執行setState)setState,會造成迴圈呼叫,然後卡到崩潰。

  • 在componentWillUnmount中呼叫setState不會觸發re-render.......因為元件都要被解除安裝了....內部儲存的狀態都被null了巴拉巴拉,不過可以在這裡去resolve一些和被解除安裝元件有關的非同步的呼叫。

  • 無狀態元件就別說生命週期函式了~,本質上就是把return的ReactElement作為自定義元件的render一樣的效果來處理,因此無狀態元件非常簡單和高效,只是為了渲染展示的。

恩,基本上需要注意的點如上,說了這些,我想說的是在React 16.0.0版本後的生命週期函式的改動很大,一方面是Fiber模式的使用(目前只是知道些概念,具體之後瞭解了再細說),另一方面,也因此,部分生命週期函式的使用會變得不推薦(給你個warning噁心你~)。

參考資料

相關文章