二、React組件的生命週期

3. 組件生命週期

  • React嚴格定義了組件的生命週期,生命週期可能會經歷以下三個過程:瀏覽器

    • 裝載過程(Mount):也就是把組件第一次在DOM樹上渲染的過程;
    • 更新過程(Updata):當組件被重新渲染的過程;
    • 卸載過程(Unmount):組件從DOM樹中刪除的過程。
  1. 三種不一樣的過程,React庫會調用組件的一些成員函數,即生命週期函數。

3.一、裝載過程

  • 當組件第一次被渲染時,依次調用的函數:服務器

    • static propTypes(createClass建立的話:propTypes)
    • static defaultProps(createClass建立的話:getDefaultProps(){})
    • constructor(初始化state;createClass建立的話:getInitalState)
    • componentWillMount
    • render
    • componentDidMount
  1. constructor函數

    ES6中每一個類的構造函數,要建立一個組件類的實例,便會調用對應的構造函數
    注意:this

    1. 並非每一個組件都須要定義本身的構造函數,無狀態的React組件每每就不須要定義構造
      函數;
    2. 一個React組件須要構造函數目的:
    • 初始化state,由於組件的生命週期中任何函數均可能要訪問state,那麼整個週期中第一個被調用的構造函數即是初始化state最理想的地方;
    • 綁定成員函數的this環境:

      - 由於在ES6語法下,類的每一個成員函數在執行時的this並非和類實例自動綁定的;
      - 而在構造函數中this就是當前組件實例,因此,爲了方便未來調用,每每在構造函數中將這個實例的特定函數綁定this爲當前類實例:code

    ...
       constructor(props){
          super(props);
          
          this.onClickFunc = this.onClickFunc.bind(this);
       }
  2. getInitialState和getDefaultProps
      1. getInitialState函數的返回值用來初始化組件的this.state;
      2. getInitialState只出如今裝載過程,也就是說一個組件的整個生命週期過程當中,這個函數只被調用一次;
      3. getDefaultProps函數的返回值能夠做爲props的初始值;
      4. 兩個函數都只有在使用React.createClass方法建立組件類時纔會用到component

    const Sample = React.createClass({
       getInitialState: function() {
           return {foo: '返回值將做爲this.state的初始值'};
       },
       getDefaultProps: function() {
           return {sampleProp: '做爲props的初始值'}
       }
     })

     5. React.createClass建立方法已經逐漸被Facebook官方廢棄
      6. 使用ES6時,在構造函數中經過this.state賦值完成狀態初始化;經過給類屬性(注意是類屬性,而不是類的實例對象的屬性)defaultProps賦值指定的props初始值:對象

    class Sample extends React.Component{
      constructor (props){
        super(props);
           this.state = {foo: '初始值'}
      }
    }
       Sample.defaultProps = {
      sampleProps: 0
    }
  3. render生命週期

    • render函數是React組件中最重要的函數,一個React組件能夠忽略其餘全部函數都不實現,但必定要實現render函數,由於全部React組件的父類React.Component類對除了render以外的生命週期函數都有默認實現。
    • 一般一個組件要發揮做用,老是要渲染一些東西,render函數並不作實際的渲染動做,它只是返回一個JSX描述結構,最終由React來操做渲染過程;
    • 當某個特殊的組件做用不是渲染界面,或者沒有東西可畫時,可以讓render函數返回null或者false,即告訴React此組件不渲染任何DOM元素;
    • 注意:render函數應該是一個純函數,徹底根據this.state和this.props來決定返回的結果,並且不要產生任何反作用,不要在render函數中調用this.setState去改變狀態,由於一個純函數不該該引發狀態的改變。
  4. componentWillMount和componentDidMount字符串

    • 在裝載過程當中,componentWillMount會在render函數以前調用,此時尚未任何東西渲染出來,即便調用this.setState修改狀態也不會發生從新繪製;
    • componentDidMount在render函數以後調用,但render調用以後並不會當即調用,而是在render函數返回的東西已經引起了渲染,組件已經被‘裝載’到了DOM樹上後,componentDidMount才被調用,此時已繪製出真實的DOM樹;
    • 注意:
    1. render函數自己並不往DOM樹上渲染或者裝載內容,它只是返回一個表示JSX表示的對象(及組件實例),而後由React庫根據返回的對象決定如何渲染;
    2. 而React庫確定是要把全部組件返回的結果綜合起來,才能知道如何產生對應的DOM修改;
    3. 因此只有React庫調用全部組件的render函數以後,纔有可能完成DOM裝載,這時候纔會依調用componentDidMount函數做爲裝載的收尾。
    4. componentWillMount能夠在服務器和瀏覽器端被調用,而componentDidMount只能在瀏覽器端被調用(由於componentDidMount是在‘裝載’完成以後被調用,且‘裝載’是一個建立組件並放到DOM樹上的過程,而服務器端渲染經過React組件產生的只是一個純粹的字符串,並不會產生DOM樹,即在服務器端不可能完成‘裝載過程’因此沒法調用componentDidMount)

3.二、更新過程

  • 隨着用戶的操做改變展現的內容,當props或者state被修改時,就會引起組件的更新過程;
  • 更新過程會依次調用如下生命週期函數,其中render函數和「裝載」過程同樣:
     - componentWillReceiveProps
     - shouldComponentUpdateget

    • componentWillUpdate
    • render
    • componentDidUpdate
  • 並非全部的更新過程都會執行所有函數。
  1. componentWillReceiveProps(nextProps)

    • 並非只有在組件的props發生改變的時候纔會調用此函數;
    • 在更新過程,只要是父組件的render函數被調用,在render函數裏被渲染的子組件就會經歷更新過程,無論父組件傳給子組件的props有沒有改變,都會觸發子組件的componentWillReceiveProps函數;
    • 注意:經過this.setState方法觸發的更新過程不會調用這個函數;
    • 由於,這個函數適合根據新的props值(也就是參數nextProps)來計算是否是要更新內部狀態state;而更新內部狀態的方法是this.setState,若是this.setState的調用致使componentWillReceiveProps再調用,那將是一個死循環。
  2. shouldComponentUpdate(nextProps,nextState)

    • 除了render函數,shouleComponentUpdate多是生命週期函數中最重要的一個函數;
    • 由於render函數決定了該渲染什麼,shouldComponentUpdate決定了一個組件何時不須要渲染;
    • render和shouldComponentUpdate也是React生命週期函數中惟二兩個要求有返回結果的函數;
    • render函數的返回結果用於構建DOM對象,shouldComponentUpdate函數返回一個布爾值,告訴React庫這個組件此次更新過程是否繼續;
    • 在更新過程當中,React庫首先調用shouldComponentUpdate函數,若是這個函數返回true,那就繼續更新過程,接下來調用render,反之則終止這次更新過程;
    • shouldComponentUpdate的參數就是接下來的props和state值;咱們能夠根據這兩個參數,外加this.props和this.state來判斷返回true或false,從而避免沒必要要的更新。
  3. componentWillUpdate和componentDidUpdate

    • 若是組件的shouldComponentUpdate返回true,React接下來調用componentWillUpdate、render和componentDidUpdate;
    • 和「裝載」過程不一樣,這對函數均可以在服務器和瀏覽器更新階段調用
    • 不過,一般在使用React作服務端渲染時,基本不會經歷更新過程,由於服務器端只須要產出HTML字符串,而一個裝載過程就足夠產出HTML字符串了,因此正常狀況下,服務器端不會調用componentDidUpdate函數,若是調用了,說明程序有錯,須要改進。

3.二、卸載過程

  • React組件的卸載過程只涉及一個函數componentWillUnmount,
  • 當React組件要從DOM樹上刪除以前,對應的componentWillUnmount函數會被調用,因此這個函數適合作一些清理性的工做。
相關文章
相關標籤/搜索