不瞭解一下React16.3的新生命週期?

前端小姐姐發表於2019-03-22

React16.3.0開始,生命週期進行了一些變化。本文主要介紹React16.3.0之後的生命週期。

React16.3.0之前生命週期:

16版本之前的react元件的生命週期相信大家已經很熟悉。16版本的react對元件的生命週期函式進行了一些修改,下面進行詳細說明。

React16.3.0之前生命週期

建立期:

  1. constructor(props, context)
  2. componentWillMount()
  3. render()
  4. componentDidMount()

執行時:

props發生變化時

  1. componentWillReceiveProps(nextProps, nextContext)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. componentWillUpdate(nextProps, nextState, nextContext)
  4. render
  5. componentDidUpdate(prevProps, prevState, snapshot)

state發生變化時

  1. shouldComponentUpdate(nextProps, nextState, nextContext)
  2. componentWillUpdate(nextProps, nextState, nextContext)
  3. render
  4. componentDidUpdate(prevProps, prevState, snapshot)

解除安裝時

componentWillUnmount()

React16.3.0之後的生命週期

建立期:

  1. constructor(props, context)
  2. static getDerivedStateFromProps(props, status)
  3. render()
  4. componentDidMount()

或者如下生命週期:

  1. constructor(props, context)
  2. componentWillMount() / UNSAFE_componentWillMount()
  3. render()
  4. componentDidMount()

注意: getDerivedStateFromProps/getSnapshotBeforeUpdate 和 componentWillMount/componentWillReceiveProps/componentWillUpdate 如果同時存在,React會在控制檯給出警告資訊,且僅執行 getDerivedStateFromProps/getSnapshotBeforeUpdate 【React@16.7.0】

執行時:

props發生變化時

  1. static getDerivedStateFromProps(props, status)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. render
  4. getSnapshotBeforeUpdate(prevProps, prevState)
  5. componentDidUpdate(prevProps, prevState, snapshot)

或者如下生命週期:

  1. componentWillReceiveProps(nextProps, nextContext)/UNSAFE_componentWillReceiveProps
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. componentWillUpdate(nextProps, nextState, nextContext)
  4. render
  5. componentDidUpdate(prevProps, prevState, snapshot)

state發生變化時

  1. static getDerivedStateFromProps(props, status)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. render
  4. getSnapshotBeforeUpdate(prevProps, prevState)
  5. componentDidUpdate(prevProps, prevState, snapshot)

或者如下生命週期:

  1. shouldComponentUpdate(nextProps, nextState, nextContext)
  2. componentWillUpdate(nextProps, nextState, nextContext)/UNSAFE_componentWillUpdate
  3. render
  4. componentDidUpdate(prevProps, prevState, snapshot)

銷燬時

componentWillUnmount()

新的生命週期圖示:

lifeCycle

生命週期詳解

1.constructor(props, context)

constructor生命週期,如不需要,可預設。通常會在 constructor 方法中初始化 state 和繫結事件處理程式。 但是,如果寫了constructor,那麼必須在其中呼叫super(props);否則可能會引起報錯。

如:

class Base extends Component {
    constructor(props) {
        super();  //應該為 super(props);
    }
    state = {
        name: this.props.name
    }
    //....code
}

複製程式碼

丟擲異常: Uncaught TypeError: Cannot read property 'name' of undefined.

同樣,如果定義了context,在state中需要使用this.context去獲取context上的內容,則需要super(props, context);

不過,如果你預設constructor,那麼在state中,可以放心的使用 this.props 或者是 this.context,不會引起報錯。

class Base extends Component {
    state = {
        name: this.props.name,
        color: this.context.color
    }
    //....code
}
複製程式碼

初始化的state同樣可以在constructor中定義。如果需要給方法繫結this,那麼統一在constructor中進行。

2.static getDerivedStateFromProps(props, state)

當元件的state需要根據props來改變的時候可呼叫此方法。這個方法是在 render() 前會被執行,每次觸發render前,都會觸發此方法。

該方法有兩個引數props和state; 返回值為state物件, 不需要返回整體state,把需要改變的state返回即可。如果不需要,可以返回null.

class Base extends Component {
    state = {
        age: 20
    }
    static getDerivedStateFromProps(props, state) {
        return {
            age: 50
        }
    }
    render() {
        // 50
        return (
            <div>{this.state.age}</div>
        )
    }
}
複製程式碼

這個方法允許元件基於 props 的變更來更新其內部狀態,以這種方式獲得的元件狀態被稱為派生狀態。應該謹慎使用派生狀態,可能會引入潛在的錯誤

3.render

React元件中必須要提供的方法。當state或者props任一資料有更新時都會執行。

render() 是一個純函式,因此,不要在其中執行setState諸如此類的操作。render必須有一個返回值,返回的資料型別可以有:

  • null、String、Number、Array、Boolean。
  • React elements
  • Fragment
  • Portal

注意不要在render中呼叫setState

4.componentDidMount

componentDidMount()方法是在元件載入完後立即執行,也就是當該元件相關的dom節點插入到dom樹中時。該方法在元件生命中只執行一次。 一般情況,我們會在這裡setState(),或者進行介面請求,設定訂閱等。

class Base extends Component {
    state = {
        age: 20
    }
    componentDidMount() {
        this.fetchDate();
    }
    render() {
        return (
            <div>{this.state.age}</div>
        )
    }
    //other code
}
複製程式碼

5.shouldComponentUpdate(nextProps, nextState, nextContext)

在渲染新的props或state前,shouldComponentUpdate被呼叫,預設返回true。forceUpdate()時不會呼叫此方法。

如果shouldComponentUpdate()返回false,那麼getSnapshotBeforeUpdate,render和componentDidUpdate不會被呼叫。

此生命週期主要用於優化效能。

6.getSnapshotBeforeUpdate(prevProps, prevState)

在render()的輸出被渲染到DOM之前被呼叫。使元件能夠在它們被更改之前捕獲當前值(如滾動位置)。這個生命週期返回的任何值都將作為第三個引數傳遞給componentDidUpdate().

7.componentDidUpdate(prevProps, prevState, snapshot)

在更新發生後呼叫 componentDidUpdate()。當元件更新時,將此作為一個機會來操作DOM。如將當前的props與以前的props進行比較(例如,如果props沒有改變,則可能不需要網路請求。

如果元件使用 getSnapshotBeforeUpdate(),則它返回的值將作為第三個“快照”引數傳遞給 componentDidUpdate()。否則,這個引數是undefined。

8.componentWillUnmount()

在元件被解除安裝並銷燬之前立即被呼叫。在此方法中執行任何必要的清理,例如使定時器無效,取消網路請求或清理在componentDidMount()中建立的任何監聽。

最後,說明一點:

componentWillUpdate,componentWillReceiveProps,componentWillUpdate這三個生命週期在React未來版本中會被廢棄。

而UNSAFE_componentWillUpdate,UNSAFE_componentWillReceiveProps,UNSAFE_componentWillUpdate 未來版本中仍可繼續使用。

初始化階段(父元件和子元件):

mount

執行階段:父元件props/state更新

子元件的shouldComponentUpdate返回false,則子元件其後的生命週期都不在進行,但是父元件的生命週期繼續執行。

update

解除安裝階段: 解除安裝父元件

unmount

參考:

  1. segmentfault.com/a/119000001…
  2. www.jianshu.com/p/514fe21b9…
  3. blog.csdn.net/qq_29311407…

更多博文閱讀,請移步(歡迎Star呀): github.com/YvetteLau/B…

相關文章