首頁  >  文章  >  web前端  >  淺析React元件的生命週期(程式碼解析)

淺析React元件的生命週期(程式碼解析)

不言
不言原創
2018-09-10 17:34:281308瀏覽

這篇文章帶給大家的內容是關於淺析React元件的生命週期(程式碼解析),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

整個React 生命週期有3個階段:建立、更新、卸載,每個階段有對應的工作和方法,我們可以看下面這個經典的圖研究一下:

淺析React元件的生命週期(程式碼解析)

第一階段

這是虛擬DOM 建立的階段,會依序執行5 個方法,這5 個方法中除了render 方法,其餘四個方法在整個生命週期中只呼叫1 次,而且一定會呼叫1 次:

  • getDefaultProps()

這個方法在元件實例創建前,也就是建構函式執行前執行,取得父元件傳來的參數,你可以在這裡編輯參數並回傳新的參數作為props

  • ##getInitalState()

元件所建立的一開始會呼叫這個方法初始化元件的state

  • componentWillMount()

在元件render 之前執行方法,可用來修改state。 React 先呼叫父元件的這個函數,再呼叫子元件的這個函數

  • render()

開始元件渲染函數,回傳一個只有一個根節點的虛擬DOM。該函數中不能同步的修改組件的狀態(state)。

  • componentDidMount()

#在 render 渲染之後,通知元件已經載入完成。 React 先呼叫子元件的這個函數,再呼叫父元件的這個函數。從這個函數開始,該元件就可以和其他框架互動了。例如設定計時器或發起網路請求。

第二階段

此時該元件已經進入了穩定運行階段,這個階段元件可以處理使用者交互,或接收事件更新介面。以下方法在整個生命週期中可以執行很多次,也可以一次也不執行。

  • componentWillReceiveProps()

#當父容器中對應的參數改變將會呼叫子元件的函數。新的 props 將會作為參數傳遞進來,舊的 props 可以根據 this.props 來取得。我們可以在該函數中對state進行一些處理。並且在該函數中更新state 不會發生二次渲染

  • shouldComponentUpdate()

該函數傳遞過來兩個參數,新的state 和新的props。 state 和 props 的改變都會調到該函數。此函數主要對傳遞過來的 nextProps 和 nextState 作判斷。如果傳回 true 則重新渲染(預設都是回傳 true),如果傳回 false 則不重新渲染。在某些特定條件下,我們可以根據傳遞過來的 props 和 state 來選擇更新或不更新,從而提高效率。

  • componentWillUpdate()

#與 componentWillMount 方法類似,在 render 渲染之前被呼叫。元件上會接收到新的 props 或 state。這個函數呼叫之後,就會把 nextProps 和 nextState 分別設定在 this.props 和 this.state 中。

  • componentDidUpdate()

與 componentDidMount 方法類似,在 render 渲染之後被調用,真實 DOM 生成之後調用函數。傳遞過來的參數是之前的 props 和 state。

第三階段

這就是消亡的階段,主要進行記憶體的清理和釋放的工作。這個階段只有一個方法,該方法在整個生命週期內被呼叫且僅呼叫一次。

  • componentWillUnmount()

#當元件要移除介面的時候,就會呼叫 componentWillUnmount。在這裡進行一些相關的銷毀操作,例如撤銷定時器,事件監聽等等。

觸發render 的幾個情況

這裡我們只考慮shouldComponentUpdate 沒有被修改,總是回傳的是true

  • 首次渲染,即Initial Render

  • 呼叫this.setState (不是每次呼叫setState 都會觸發,react 會最佳化,例如antd 的input 元件)

  • 父元件發生更新,通常是修改的子元件的props

  • 如果父元件觸發了render, 子元件當然也會相應觸發render

  • ##調用this.forceUpdate()
  • 一個簡單的範例
import React from 'react';
import ReactDOM from 'react-dom';
import style from './font.css';
import './index.less';

class Parent extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      willRender: true,
      prop: 1
    };
  }

  render(){
    return (
      <div>
        <button>{this.setState({prop: 10})}}>changePropsFromParent</button>
        {
          this.state.willRender &&
          <child></child>
        }
        <button>{this.setState({willRender: false})}}>UnmountChild</button>
      </div>
    );
  }
}

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      curr: 0
    };
  }

 getDefaultProps(){
   console.log('getDefaultProps');
 }

  getInitalState(){
    console.log('getInitalState');
  }

  componentWillMount(){
    console.log('componentWillMount');
  }

  componentDidMount(){
    console.log('componentDidMount');
  }

  componentWillReceiveProps(){
    console.log('componentWillReceiveProps');
  }

  shouldComponentUpdate(){
    console.log('shouldComponentUpdate');
    return true;
  }

  componentWillUpdate(){
    console.log('componentWillUpdate');
  }

  componentDidUpdate(){
    console.log('componentDidUpdate');
  }

  componentWillUnmount(){
    console.log('componentWillUnmount');
  }

  render() {
    console.log('render')

    return (
      <div>
        <button>this.setState({curr:2})}>setState</button>
        <button>{this.forceUpdate();}}>forceUpdate</button>
      </div>
    );
  }
}

ReactDOM.render(
  <parent></parent>,
  document.getElementById('root')
);

相關推薦:

##React元件生命週期實例分析


React Native元件的生命週期多長

以上是淺析React元件的生命週期(程式碼解析)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn