React生命週期簡明寶典

AddOneG發表於2018-03-17

介紹

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》

相關文章