在 初探 State、Class Component State 語法、State 內部運作原理 這三個篇章中介紹了 state 的概念、用法與運作原理。
如果讀者還記得前幾篇提到的小時鐘範例,範例中,Clock
Component 在 componentDidMount
函式中設定 timer,每秒去更改 component 的 state,並在 componentWillUnmount
函式中把 timer 清除。
componentDidMount
與 componentWillUnmount
這兩個函式都是 React 提供的 class component 生命週期函式(Lifecycle methods),可用來供開發者在 component 的各個生命週期(Lifecycle)中自定義要執行的動作。
這個篇章將介紹何謂 React component 的生命週期(Lifecycle),而 Component 生命週期函式(Lifecycle methods) 又是什麼,期待讓讀者能更進一步掌握 component 的運作方式。
就讓我們直接進入主題:React component 生命週期(Lifecycle) 吧!
Lifecycle 代表著 React component 建立出來的 instance 的各個生命階段。
就像是人會生、老、病、死一樣,對 React component 的 instance 來說,它們會有創建(Mounting)、更新(Updating)、刪除(Unmounting) 這三個生命週期。
也如同每個人都是各自的個體,擁有自己的生老病死時間一樣,每個 component 的 instance 也有自己獨立的生命週期。
React 在 class component 中有提供幾個內建函式,分別會在不同的 lifecycle 時期執行。這些函式即為生命週期函式(Lifecycle methods)。
只要開發者實作/覆寫 lifecycle methods,React 就會在 component instance 對應的時期執行 lifecycle methods 的函式內容。
接著讓我們來概覽 React component instance 的生命週期。
如 何謂 React component lifecycle 段落所述, React component 創建出來的 instance 會經過三個生命週期:
每個時期中又可分為三個子階段:
以下這張圖即可以很清楚的表達 React component instance 的生命週期:
^16.4
。讀者們也可以到生命週期網頁版查看上面的 lifecycle methods。到這邊為止已經了解了何謂 lifecycle 以及知道一個 React component 的 instance 會有哪些生命週期。
接下來的幾個段落會分別介紹 Lifecycle 的各個時期:創建(Mounting)、更新(Updating)與 刪除(Unmounting)。
另外,Lifecycle 的每個時期可以對應到概覽圖中的一直排(Column)。讀者閱讀時也可以同時參考概覽圖。
Mounting (創建) 時期是發生在 component 的 instance 剛建立出來,並被加入 DOM 中的時候。如下圖紅色直排所示:
就像一般物件導向語言中每個 instance 只會被初始化一次一樣,一個 React class component 的 instance 只會經歷一次 Mounting 時期。
具體一點來說,React 在 Mounting 時期大致上會做以下幾個步驟:
初始化 component instance
首先,就像一般語言的 class instance 一樣,React 也會先執行 component class 的 constructor
來初始化並將 component instance 創建出來。
產出 Component 自定義的 React element
接著,React 會執行 render
以產出 Component 自定義的 React element 內容。
請注意,React element 只是模擬 DOM element 的 JavaScript object 而已。到目前為止,內容都還未被實際更新到 DOM 上。
把 Virtual DOM snapshot 產出來,並跟之前的 Virtual DOM snapshot 比較
React 會在把 Virtual DOM snapshot 產出來,並與上一個產出的 Virtual DOM snapshot 做比較(Diff),決定哪些內容是要實際被更新到 DOM 上的。
把差異的的部分實際更新到 DOM 上
最後,React 會把 Virtual DOM Diff 完不同的內容實際更新到 DOM 上。剛創建出來的 element 就這樣顯示到畫面上了。
除此之外,React 也會觸發一些 lifecycle methods,這些函式將在之後介紹。
Updating (更新) 時期會在 component instance 的 props 或 state 被更新(setState
),亦或者被強制更新(forceUpdate
)時觸發。如下圖紅色直排所示:
由於一個 component instance 的 props 與 state 可以被多次更改,因此一個 component instance 可能經歷多次的 Updating 時期。
具體一點來說,React 在 Updating 時期大致上會做以下幾個步驟:
決定 Component 是否更新
首先,React 會通過 shouldComponentUpdate
回傳的值決定這個 lifecycle method 決定 component instance 到底要不要更新。
重新產出 Component 自定義的 React element
接著,React 會再次執行 render
以產出 Component 自定義的 React element 內容。此內容通樣尚未實際放到 DOM 上。
把 Virtual DOM snapshot 產出來,並跟之前的 Virtual DOM snapshot 比較
React 會在把 Virtual DOM snapshot 產出來,並與上一個產出的 Virtual DOM snapshot 做比較(Diff),決定哪些內容是要實際被更新到 DOM 上的。
把差異的的部分實際更新到 DOM 上
最後,React 會把 Virtual DOM Diff 完不同的內容實際更新到 DOM 上。剛創建出來的 element 就這樣顯示到畫面上了。
除此之外,React 也會觸發一些 lifecycle methods,這些函式將在之後介紹。
從這些步驟中可以發現,React 在 Updating 時期執行的 2
3
4
步驟其實與 Mounting 階段幾乎相同,只差在 React 呼叫的 lifecycle methods 不同而已。這是因為 Mounting 與 Updating 兩個週期都有同樣的 Render 階段 與 Commit 階段。
Unmounting (刪除) 時期會在 component 的 instance 要被刪除,並從 DOM 裡移除時觸發。如下圖紅色直排所示:
由於一個 component instance 刪除之後就不會存在了,因此一個 React class component 的 instance 只會經歷一次 Unmounting 時期。
具體一點來說,React 在 Unmounting 時期大致上只會做兩個步驟:
把 component instance 釋放掉
執行 lifecycle method:componentWillUnmount
,其中開發者可以把一些註冊的內容給釋放掉(例如:把 setInterval
可用 clearInterval
清除掉)。
把 component instance 從 DOM 上移除
最後,React 會實際把 component 從 DOM 上移除。Component instance 的一生就此結束。
需要一提的事,component lifecycle 其實還有一個隱藏的週期:Error Handling (刪除) 時期。
Error Handling 時期只會在 contructor
、render
或其他 lifecycle methods 出錯時被觸發。
相關內容將在之後的章節中介紹。
在這個章節,我們了解了 React component instance 的生命週期(Lifecycle)代表一個 component instance 各個生命階段。
而每個生命週期都有提供對應的生命週期函式(Lifecycle methods),讓開發者在 component instance 對應的時期執行函式內容。
Component instance 生命週期有三個:
每個週期又分為三個階段:
目前已經介紹完各時期的內部運作步驟了,下個章節將換個方式,從生命週期階段(Lifecycle phases)的角度下去了解整個 Lifecycle。