介紹
React的生命週期是我們掌握React工作過程所必須掌握的知識,同時也是部分公司的面試考點
概要
React嚴格定義了元件的生命週期,其主要經歷瞭如下三個過程
- 裝載過程(Mount): 元件第一次在DOM樹中渲染的過程
- 更新過程(Update): 元件重新渲染的過程
- 解除安裝過程(Unmount): 元件從DOM中刪除的過程
裝載過程
元件第一次被渲染的時候,依次呼叫的函式為:
- constructor
- getInitialState
- getDefaultProps
- componentWillMount
- render
- componentDidMount
1. constructor
ES6中每個類的建構函式,要建立一個元件的例項就要呼叫相應的建構函式。 但是並不是每個元件都要定義自己的建構函式,比如無狀態的React元件。一個元件呼叫建構函式,往往是為了兩個目的:
- 初始化state
- 繫結成員函式的this環境
getInitialState和getDefaultProps
getInitialState:該函式返回值用來初始化state getDefaultProps: 該函式返回值用來初始化props
這兩者只有用React.createClass方法創造的元件類才會發生作用,並且React.createClass已經被Fb官方廢棄,所以這裡不細講了
2. componentWillMount
這個函式沒什麼存在感,因為在這個時候沒有任何渲染出來的結果,呼叫setState修改狀態也不會觸發重新渲染,並且在這裡做的事情完全可以提前到constructor中去做
3. render
可以說React元件中最重要的函式,因為React元件的父類React.Component類對除render之外的生命週期函式都有預設實現
render並不做渲染工作,只是返回一個JSX描述的結構,最終由React庫根據返回物件決定如何渲染
render應該是一個純函式,完全根據state和props來決定返回結果,而不產生副作用,所以render中呼叫setState是錯的,因為純函式不應該引起狀態的改變
4. componentDidMount
componentDidMount並不是在render呼叫後立即呼叫,其呼叫的時候render返回的JSX已經渲染了
componentWillMount可以在服務端和瀏覽器端呼叫,但是componentDidMount只能在瀏覽器端呼叫(因為"裝載"過程是不可能在服務端完成的)
非同步請求資料一般都在該函式內進行。
更新過程
更新過程會依次呼叫以下生命週期函式:
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
更新過程並不總是執行所有函式
1. componentWillReceiveProps
只要是父元件的render函式被呼叫,在render裡渲染的子元件就會經歷更新過程,不管父元件傳遞給子元件的props有沒有改變,都會觸發componentWillReceiveProps。
注意通過setState觸發的更新過程不會呼叫這個函式,不然豈不是死迴圈了?
2. shouldComponentUpdate
應該是除了render之外最重要的函式了。它決定了一個元件什麼時候需不需要渲染。 render和shouldComponentUpdate是React中唯二需要有返回值的函式,shouldComponentUpdate返回一個布林值,告訴React是否需要繼續更新,若為true則繼續,為false則停止更新,不會觸發之後的重新渲染。
3. componentWillUpdate
即將render時執行,初始化render時不執行。在這裡同樣不能setState, 這個函式呼叫之後,就會把nextProps和nextState分別設定到rops和state中,緊接著呼叫render
4. render
同上
5. componentDidUpdate
元件更新完成後執行,初始化render時不執行
解除安裝過程
解除安裝過程只有一個函式componentWillUnmount,當react元件要從DOM樹上刪除前,該函式會被呼叫,所以這個函式適合做一些清理工作。
eg: 在componentDidMount中用非react方法建立的DOM元素,如果不處理可能會發生記憶體洩漏,因此可以在該函式中將其清理乾淨
總結
React的生命週期函式並沒有想象中的那麼複雜
參考於《深入理解React》