1. 程式人生 > >React學習-- React原始碼(3)生命週期的管理藝術

React學習-- React原始碼(3)生命週期的管理藝術

React的主要思想是通過構建可複用元件來構建使用者介面。

元件:其實就是有限狀態機,通過狀態渲染對應的介面,且每個元件都有自己的生命週期,它規定了元件的狀態和方法需要在那個階段改變和執行。

例如:某個元件有顯示和隱藏兩個狀態,在React中,只需要設定狀態setState({ showed: true/false })就可以實現顯示和隱藏的切換。

React生命週期基礎

1、當首次掛載元件時,順序執行:getDefaultProps,getInitialState,componentWillMount,render,componentDidMount 。
2、當解除安裝元件時,執行componentWillUnmount。
3、當重新掛在元件的時,按順序執行:getInitialState,componentWillMount,render,componentDidMount。但是不執行getDefaultProps
4、當再次渲染元件時,元件接收到更新狀態,此時按順序執行:componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,render,componentDidUpdate。

如果開發者使用ES6 classes的方法構建React元件,那麼defaultProps={}其實就是呼叫內部的getDefaultProps方法,this.state = {}其實就是呼叫getInitialState方法。

React生命週期進階

自定義元件的生命週期主要通過三個階段進行管理:MOUNTING、RECEIVE_PROPS、UNMOUNTING,它們負責通知元件當前所處的階段,應該執行生命週期中的哪個步驟。這三個階段對應三種方法:mountComponent、updateComponent、unmountComponent。在每個方法中,都提供了集中處理方法,其中前置will的在進入狀態前呼叫,字首did的在進入狀態之後呼叫。

1、建立自定義元件

createClass時建立自定義元件的入口方法。該方法在整個生命週期中只會執行一次。這個方法負責管理生命週期中的getDefaultProps,因此這個方法也將只執行一次。

2、階段一:MOUNTING

mountComponent負責管理生命週期中的方法:getInitialState、componentWillMount、render、componentDidMount。

通過mountComponent掛載元件,初始化序號、標記等引數,判斷是否為無狀態元件,並進行初始化工作,比如初始化props、context等引數。利用getInitialState獲取初始化state、初始化更新佇列和更新狀態。

如果元件中存在componentWillMount,則執行。如果在componentWillMount中呼叫了setState方法,則會進行state合併,而不是re-render。並且,inst.state = this._processPendingState (inst.props, inst.context) 方法是在componentWillMount之後執行的,因此componentWillMount方法中的state並不是最新的。

渲染完成後,若存在componentDidMount則呼叫。

如果元件存在子元件,那麼父元件的componentWillMount在子元件的componentWillMount之前呼叫;父元件的componentDidMount在子元件的componentDidMount之後呼叫(因為mountComponent是通過遞迴渲染內容的)。

這裡寫圖片描述

3、階段二:RECEIVE_PROPS

updateComponent負責管理生命週期中的:componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate。

若存在componentWillReceiveProps,則執行。如果此時在componentWillReceiveProps中呼叫setState,是不會觸發re-render的,而是會進行state合併。並且,在componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate中也還是無法獲取到更新後的 this.state,只有在render、componentDidUpdate中才能獲取到更新後的this.state。

注意,禁止在shouldComponentUpdate和componentWillUpdate中呼叫setstate,這會造成迴圈呼叫,直至耗光瀏覽器記憶體後崩潰。

這裡寫圖片描述

4、階段三:UNMOUNTING

unmountComponent負責管理生命週期中的unmountComponent。

如果存在unmountComponent,則執行並重置所有相關引數,更新佇列和狀態,如果此時在unmountComponent中呼叫setState,是不會觸發re-render的。

生命週期和狀態讓React元件非常靈活和強大,但是同時可能也會導致元件變的複雜而難以維護。

在實際的專案中,我們經常需要編寫一些自身沒有狀態,只是從父元件接收props,並根據這些props進行渲染的簡單元件。

在React中,一個很重要的原則就是讓元件儘可能的都是無狀態的。

無狀態元件

無狀態元件只是一個render方法,沒有狀態,沒有生命週期,只是簡單的接收props渲染生成DOM結構,是一個純粹為了渲染而生的元件。相比於有狀態元件,它們簡單快捷高效,所以如果有可能的話,請儘量使用無狀態元件。

例子:

const HelloWorld = (props) => <div>{props.name}</div>; ReactDOM.render(<HelloWorld name="Hello World!" />, App);

這裡寫圖片描述