React 的生命週期變化

React 從 v16.3 開始,對生命週期進行了漸進式的調整。廢棄了一些生命週期方法和添加了一些新的生命週期方法。html

原生命週期

原生命週期圖

新的生命週期

新的生命週期圖

React 逐漸廢棄的生命週期方法

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

雖然廢棄了這幾個生命週期方法,可是 React 爲了遵循版本兼容,因此 v16.3 並無刪除這三個方法,而且還增長了UNSAFE_componentWillMount,UNSAFE_componentWillReceivePropsUNSAFE_componentWillUpdate方法,在 v16.3 版本中 新舊這幾個方法均可以使用。 在 v16.3 之後的 v16.x版本中,新舊的方法依舊均可以使用,可是使用不帶UNSAFE_前綴的方法,將提示被棄用的警告。 在v17 將刪除componentWillMountcomponentWillReceivePropscomponentWillUpdate,只有帶有UNSAFE_前綴新的生命週期方法可使用。react

React 新添加的生命週期方法

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

組件的生命週期分爲:掛載、更新、卸載。ajax

掛載

組件建立實例並插入 DOM 時,按照下面的生命週期方法順序調用數組

  • constructor()
  • static getDerivedStateFromProps()
  • componentWillMount()/UNSAFE_componentWillMount() 將被棄用
  • render()
  • componentDidMount()

在有定義static getDerivedStateFromProps()componentWillMount()/UNSAFE_componentWillMount()將無效。服務器

constructor()網絡

constructor(props)
複製代碼

React 組件在掛載前,會調用它的構造函數,在構造函數內部必須執行一次super(props)。不能再constructor內部調用this.setState。 一般用於:函數

  • 經過給this.state初始化內部狀態
  • 爲事件處理函數綁定this

static getDerivedStateFromProps()性能

static getDerivedStateFromProps(newProps,prevState)
複製代碼

是一個靜態方法,父組件傳入的newProps和當前組件的prevState進行比較,判斷時候須要更新state,返回值對象用做更新state,若是不須要則返回nullui

render()方法以前調用,而且在初始掛載和後續更新時調用。this

import * as React from "react";
class App extends React.Component{
	constructor(props){
		super(props);
		this.state={
			childDown:1,
			num:0
		}
	}
	static getDerivedStateFromProps(props,state){
	    if(props.isDown === state.childDown){
	        return {
	            num:state.childDown
	        }
	    }
	    return null 
	}
	render(){
        return(
            <div>22</div>
        )
    }
}
複製代碼

componentWillMount()/UNSAFE_componentWillMount() 棄用 在掛載以前調用。在render()以前調用。在此方法中調用setState不會觸發render

有的習慣把請求放在此階段中,但更推薦放在componentMidMount()中。 在服務器渲染時,在此方法中同步數據,但建議使用constructor來初始化數據。

render()

render()是組件中惟一必須實現的方法。

react()是做爲渲染用的,能夠返回如下類型

  • React 元素
  • 數組或fragments
  • Portals
  • 字符串或者數值類型
  • 布爾類型或null

render() 函數應該是純函數。不可以調用setState

componentDidMount()

組件加載完成,可以獲取真是的 DOM 在此階段能夠ajax請求綁定事件,在此階段綁定了時間要在componentWillUnmount()取消。在此階段能夠調用setState,觸發render渲染,但會影響性能。

更新

  • componentWillReceiveProps()/UNSAFE_componentWillReceiveProps() 棄用
  • static getDerivedStateFromProps()
  • shouldComponentUpate()
  • componentWillUpdate()/UNSAFE_componentWillUpdate() 棄用
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate

getDerivedStateFromPropsgetSnapshotBeforeUpdate時,componentWillReceiveProps()/UNSAFE_componentWillReceiveProps()componentWillUpdate()/UNSAFE_componentWillUpdate()無效。

componentWillReceiveProps()/UNSAFE_componentWillReceiveProps() 棄用

UNSAFE_componentWillReceiveProps(nextprops){}
複製代碼

在已掛載的組件接收新的props以前調用,通常用這個方法判斷props的先後變化來更新state

須要注意的是,若是父組件致使組件從新渲染,那麼即便props沒有更改,也會調用次方法。

該方法將被棄用,建議使用getDeviedStateFromProps

import * as React from "react";
class App extends React.Component {
  state = {
    isWill: false,
  };

  componentWillReceiveProps(nextProps) {
    if (this.props.cur !== nextProps.cur) {
      this.setState({
        isWill:
          nextProps.cur > this.props.cur,
      });
    }
  }
  render(){
     return(
         <div>22</div>
     )
  }
}
複製代碼

static getDerivedStateFromProps()

和掛載階段一致。

shouldComponentUpdate()

shouldComponentUpdate(props,state)
複製代碼

在已掛載的組件,當props或者state發生變化時,會在渲染前調用。

根據父組件的 props 和當前的 state 進行對比,返回true/false。決定是否觸發後續的 UNSAFE_componentWillUpdate()render()componentDidUpdate()

React 可能將shouldComponentUpdate()認爲不嚴格的指令,即便statefalse,也有可能致使組件從新渲染。

import * as React from "react";
class App extends React.Component {
  state = {
    isWill: false,
  };

  shouldComponentUpdate(props,state){ 
       if(props.val !== state.val){
           console.log("shouldComponentUpdate");
           return true
       }
   }
   render(){
        return(
            <div>22</div>
        )
    }
}
複製代碼

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate(prevProps,prevSteate)
複製代碼

在真是的 DOM 更新前調用。可獲取一些有用的信息而後做爲參數傳遞給componentDidUpdate()prevProps表示更新前的props,prevState表示更新前的state

render()以後componentDidUpdate()以前調用。此方法的返回值(snaphot)可做爲componentDidUpdate()的第三個參數使用。如不須要返回值則直接返回null

getSnapshotBeforeUpdate()須要和componentDidUpdate()搭配。

componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot)
複製代碼

該方法會在更新完成後當即調用。首次渲染不會執行此方法。

當組件更新後,能夠在此處對 DOM 進行操做。

能夠在此階段使用setState,觸發render()但必須包裹在一個條件語句裏,以免死循環。

卸載

  • componentWillUnmount()
componentWillUnmount()
複製代碼

會在組件卸載和銷燬以前直接調用。此方法主要用來執行一些清理工做,例如:定時器,清除事件綁定,取消網絡請求。

此階段不能調用setState,由於組件永遠不會從新渲染。

總結

React 的生命週期能夠查看 生命週期圖譜

雖然 React 作了向下兼容,但仍是推薦你們逐漸使用新的生命週期方法。

更多詳情請移步React 生命週期

相關文章
相關標籤/搜索