面試官:說說你對react生命周期的理解
hello派近,這里是瀟晨,今天我們來看下react
生命周期在各個階段是怎樣執(zhí)行的洁桌,在面試的過程中有沒有遇到這個問題呢渴丸,大家也可以學習往期react
源碼體系文章哦,往期文章目錄在文章結(jié)尾另凌。
在之前的react
源碼介紹中谱轨,我們可以將應用的渲染過程分為mount
階段(應用首次渲染)和update
階段(應用狀態(tài)更新),無論在mount
階段還是update
階段吠谢,都會經(jīng)歷兩個子階段土童,一個是render
階段,一個是commit
階段工坊。
-
mount
時:- 在
render
階段會根據(jù)jsx
對象構(gòu)建新的workInProgressFiber
樹献汗,不太了解Fiber
雙緩存的可以查看往期文章 Fiber架構(gòu),然后將相應的fiber
節(jié)點標記為Placement
王污,表示這個fiber
節(jié)點需要被插入到dom
樹中罢吃,然后會這些帶有副作用的fiber
節(jié)點加入一條叫做Effect List
的鏈表中。 - 在
commit
階段會遍歷render
階段形成的Effect List
昭齐,執(zhí)行鏈表上相應fiber
節(jié)點的副作用尿招,比如Placement
插入,或者執(zhí)行Passive
(useEffect
的副作用)阱驾。將這些副作用應用到真實節(jié)點上
- 在
-
update
時:- 在
render
階段會根據(jù)最新狀態(tài)的jsx
對象對比current Fiber
就谜,再構(gòu)建新的workInProgressFiber
樹,這個對比的過程就是diff
算法里覆,diff
算法又分成單節(jié)點的對比和多節(jié)點的對比吁伺,不太清楚的同學參見之前的文章 diff算法 ,對比的過程中同樣會經(jīng)歷收集副作用的過程租谈,也就是將對比出來的差異標記出來篮奄,加入Effect List
中,這些對比出來的副作用例如:Placement
(插入)割去、Update
(更新)窟却、Deletion
(刪除)等。 - 在
commit
階段同樣會遍歷Effect List
呻逆,將這些fiber
節(jié)點上的副作用應用到真實節(jié)點上
- 在
為什么要先講render
在mount
和update
階段的整體流程呢夸赫,這是因為react
生命周期就是穿插在這些子階段中執(zhí)行的,來看一張圖
-
render
階段:-
mount
時:組件首先會經(jīng)歷constructor
咖城、getDerivedStateFromProps
茬腿、componnetWillMount
呼奢、render
-
update
時:組件首先會經(jīng)歷componentWillReceiveProps
、getDerivedStateFromProps
切平、shouldComponentUpdate
握础、render
-
error
時:會調(diào)用getDerivedStateFromError
-
-
commit
階段-
mount
時:組件會經(jīng)歷componnetDidMount
-
update
時:組件會調(diào)用getSnapshotBeforeUpdate
、componnetDidUpdate
-
unMount
時:調(diào)用componnetWillUnmount
-
error
時:調(diào)用componnetDidCatch
-
其中紅色的部分不建議使用悴品,需要注意的是commit
階段生命周期在mutation
各個子階段的執(zhí)行順序禀综,可以復習上一章
接下來根據(jù)一個例子來講解在mount
時和update
時更新的具體順序:
-
mount
時:首先會按照深度優(yōu)先的方式,依次構(gòu)建wip Fiber
節(jié)點然后切換成current Fiber
苔严,在render
階段會依次執(zhí)行各個節(jié)點的constructor
定枷、getDerivedStateFromProps
/componnetWillMount
、render
届氢,在commit
階段欠窒,也就是深度優(yōu)先遍歷向上冒泡的時候依次執(zhí)行節(jié)點的componnetDidMount
-
update
時:同樣會深度優(yōu)先構(gòu)建wip Fiber
樹,在構(gòu)建的過程中會diff
子節(jié)點退子,在render
階段贱迟,如果返現(xiàn)有節(jié)點的變化,例如上圖的c2絮供,那就標記這個節(jié)點Update Flag
,然后執(zhí)行getDerivedStateFromProps
和render
茶敏,在commit
階段會依次執(zhí)行節(jié)點的getSnapshotBeforeUpdate
壤靶、componnetDidUpdate