面試官:說說你對react生命週期的理解
hello,這裡是瀟晨,今天我們來看下react
生命週期在各個階段是怎樣執行的,在面試的過程中有沒有遇到這個問題呢,大家也可以學習往期react
原始碼體系文章哦,往期文章目錄在文章結尾。
在之前的react
原始碼介紹中,我們可以將應用的渲染過程分為mount
階段(應用首次渲染)和update
階段(應用狀態更新),無論在mount
階段還是update
階段,都會經歷兩個子階段,一個是render
階段,一個是commit
階段。
mount
時:- 在
render
階段會根據jsx
物件構建新的workInProgressFiber
樹,不太瞭解Fiber
雙快取的可以檢視往期文章 Fiber架構,然後將相應的fiber
節點標記為Placement
,表示這個fiber
節點需要被插入到dom
樹中,然後會這些帶有副作用的fiber
節點加入一條叫做Effect List
的連結串列中。 - 在
commit
階段會遍歷render
階段形成的Effect List
,執行連結串列上相應fiber
節點的副作用,比如Placement
插入,或者執行Passive
(useEffect
的副作用)。將這些副作用應用到真實節點上
- 在
update
時:- 在
render
階段會根據最新狀態的jsx
物件對比current Fiber
,再構建新的workInProgressFiber
樹,這個對比的過程就是diff
演算法,diff
演算法又分成單節點的對比和多節點的對比,不太清楚的同學參見之前的文章 diff演算法 ,對比的過程中同樣會經歷收集副作用的過程,也就是將對比出來的差異標記出來,加入Effect List
中,這些對比出來的副作用例如:Placement
(插入)、Update
(更新)、Deletion
(刪除)等。 - 在
commit
階段同樣會遍歷Effect List
,將這些fiber
節點上的副作用應用到真實節點上
- 在
為什麼要先講render
在mount
和update
階段的整體流程呢,這是因為react
生命週期就是穿插在這些子階段中執行的,來看一張圖
render
階段:mount
時:元件首先會經歷constructor
、getDerivedStateFromProps
、componnetWillMount
、render
update
時:元件首先會經歷componentWillReceiveProps
、getDerivedStateFromProps
、shouldComponentUpdate
、render
error
時:會呼叫getDerivedStateFromError
commit
階段mount
時:元件會經歷componnetDidMount
update
時:元件會呼叫getSnapshotBeforeUpdate
、componnetDidUpdate
unMount
時:呼叫componnetWillUnmount
error
時:呼叫componnetDidCatch
其中紅色的部分不建議使用,需要注意的是commit
階段生命週期在mutation
各個子階段的執行順序,可以複習上一章
接下來根據一個例子來講解在mount
時和update
時更新的具體順序:
mount
時:首先會按照深度優先的方式,依次構建wip Fiber
節點然後切換成current Fiber
,在render
階段會依次執行各個節點的constructor
、getDerivedStateFromProps
/componnetWillMount
、render
,在commit
階段,也就是深度優先遍歷向上冒泡的時候依次執行節點的componnetDidMount
update
時:同樣會深度優先構建wip Fiber
樹,在構建的過程中會diff
子節點,在render
階段,如果返現有節點的變化,例如上圖的c2,那就標記這個節點Update Flag
,然後執行getDerivedStateFromProps
和render
,在commit
階段會依次執行節點的getSnapshotBeforeUpdate
、componnetDidUpdate