一篇便可瞭解react16先後的生命週期

react16前的生命週期

在react16的以前生命週期其實主要分爲四個階段:組件初始化、組件掛載、組件更新、組件卸載。
javascript

image.png

組件初始化階段

constructor

在該階段組件中的構造方法 constructor() 接受 props 接收父組件傳下來的 props。還能夠在 constructor() 內部定義定義this.state 的初始內容。注意:在組件中寫了 constructor 方法就必須在裏面使用 super(),而且應在其餘語句以前前調用 super(props)。不然,this.props 在構造函數中可能會出現未定義的 bug。html

constructor(props) {
  super(props)
  console.log(this.props) // 在內部可使用props
  this.state = {
    //定義state初始值
  }
}
複製代碼

組件掛載階段

componentWillMount

在組件將要掛載到 DOM 前調用,只會被調用一次,在該方法中修改 state 的值,並不會引發組件從新渲染。(數據請求等異步操做不建議寫在該方法內,異步操做可能阻塞 UI)。java

componentWillMount(){}
複製代碼

render()

該函數會建立一個虛擬 DOM,用來表示組件的輸出。只能經過 this.props 和 this.state 訪問數據,且不能在裏面執行 this.setState 更該組件狀態。在 render 中能夠返回 null、false 或者任何 React 組件,只能出現一個頂級組件,不能返回一組元素(在 react16 中有所改善,能夠返回一組元素或單個字符串)。react

Render(){
	return (
  		// react組件
  )
}
複製代碼

componentDidMount

組件掛載到 Dom 後調用,且只調用一次。此時組件已經生成對應的 DOM 結構,能夠在該函數中經過ReactDOM.findDOMNode()訪問到真實的 DOM 或者經過 this.refs.[refName] 屬性獲取真實 DOM 。(數據請求等異步操做建議寫在該方法內)bash

componentDidMount() {
  // 進行異步數據請求或者獲取dom
}
複製代碼

組件更新階段

componentWillReceiveProps

該函數接受一個參數 nextProps,當父組件重傳props時會調用。拿到新的 props 與舊的 props 來比較是否變化,若變化能夠經過 this.setState 更新 state。固然也能夠不比較新舊 props 值直接更新 state。dom

componentWillReceiveProps(nextProps) {
  // 示例
  if (nextProps.state !== this.props.state) {
     this.setState({
       state: nextProps.state 
     });
  }
}
複製代碼

官方提示:在componentWillReceiveProps中調用 this.setState() 將不會引發第二次渲染。異步

因爲每次子組件接收到新的props,都會從新渲染一次,除非你使用 shouldComponentUpdate 來阻止從新渲染,可是你能夠 componentWillReceiveProps 中根據新的 props 更新 state,雖然更新state也會觸發一次從新渲染,但並不會觸發額外的render。函數

shouldComponentUpdate(nextProps,nextState)

該函數是惟一能夠控制組件渲染的生命週期。若是 props 和 state 的改變不須要從新渲染組件。則能夠在該函數內返回 false,阻止組件的從新渲染。爲了優化組件性能,減小組件的沒必要要渲染。性能

shouldComponentUpdate(nextProps, nextState){
  // return true 更新組件
  // return false 則不更新組件
}
複製代碼

componentWillUpdate(nextProps,nextState)

shouldComponentUpdate 方法返回 true 後,在組件即將進行從新渲染前調用該函數(注意不要裏面去更新 props 或者 state,會致使組件進入死循環),在這以後會調用 render 方法進行從新渲染。優化

componentWillUpdate(nextProps,nextState) {
  // 不要在此處更新props或state
}
複製代碼

componentDidUpdate(prevProps,prevState)

組件被從新渲染後該方法會被調用,能夠拿到更新前的 props 和 state 。除了首次渲染時調用的componentDidMount,以後每次渲染都會調用該函數。和 componentDidMount 相似的是能夠在這裏操做更新後的DOM。

componentDidUpdate(prevProps,prevState) {}
複製代碼

組件卸載階段

componentWillUnmount

該函數在組件卸載前被調用,能夠在執行一些清理工做,好比清除組件中使用的定時器或者事件監聽器,以免引發內存泄漏。

componentWillUnmount() {
  // 清除定時器或事件監聽器
}
複製代碼

react16的生命週期

react16的生命週期新引入了三個新的生命週期函數:getDerivedStateFromProps,getSnapshotBeforeUpdate,componentDidCatch,棄用的三個生命週期函數:componentWillMount、componentWillReceivePorps,componentWillUpdate。其餘的生命週期功能與前面介紹的相同。

getDerivedStateFromProps(props, state)

該函數在組件掛載階段和後續更新階段調用,根據 props 和 state 兩個參數,計算出預期的狀態改變,返回一個對象表示新的 state進行更新;若是不須要更新,返回 null 便可。該函數用來替代 componentWillReceiveProps。

static getDerivedStateFromProps(props, state) {
  //根據props和state計算出預期的狀態改變,返回結果會被送給setState
}
複製代碼

getSnapshotBeforeUpdate(prevProps, prevState)

該函數在render以後被調用,能夠讀取但沒法使用DOM的時候。它使得組件能在發生更改以前從 DOM 中捕獲一些信息(例如,滾動位置)。返回值將做爲componentDidUpdate的第三個參數。該函數配合componentDidUpdate, 能夠替代componentWillUpdate。

getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log('getSnapshotBeforeUpdate');
    return 'react16';
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log('snapshot = ', snapshot);
  }
複製代碼

static getDerivedStateFromError()

今生命週期會在後代組件拋出錯誤後被調用。 它將拋出的錯誤做爲參數,並返回一個值以更新 state。

static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染能夠顯降級 UI
    return { hasError: true };
  }
複製代碼

componentDidCatch(error,info)

任何一處的javascript會觸發該函數。

componentDidCatch(error, info) {
  // 獲取到javascript錯誤
}
複製代碼

總結

react16更新後的生命週期能夠總結爲:

組件掛載階段
  • constructor
  • getDerivedStateFromProps
  • render
  • componentDidMount
組件更新階段
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate
組件卸載階段
  • componentWillUnmount

image.png

參考連接:

相關文章
相關標籤/搜索