8-生命周期

React 組件的生命周期

React.js 將組件渲染,并且構(gòu)造 DOM 元素然后塞入頁面的過程稱為組件的掛載。這一節(jié)我們學(xué)習(xí)了 React.js 控制組件在頁面上掛載和刪除過程里面幾個(gè)方法:
componentWillMount:組件掛載開始之前,也就是在組件調(diào)用 render 方法之前調(diào)用。
componentDidMount:組件掛載完成以后,也就是 DOM 元素已經(jīng)插入頁面后調(diào)用。
componentWillUnmount:組件對(duì)應(yīng)的 DOM 元素從頁面中刪除之前調(diào)用。

現(xiàn)在我們應(yīng)該知道一件事情, 有了 組件 和 props, 我們就可以把一個(gè)頁面拆成一個(gè)個(gè)小組件.

有了 內(nèi)部狀態(tài), 我們就可以讓組件在某些時(shí)候做出一些變化.

我們的頁面就是通過一個(gè)個(gè)小的組件, 組合成一個(gè)大的組件, 一份份小的 jsx, 組合成一份大的 jsx.

最后交給 ReactDOM.render(), 通過 DOM 操作, 把 Virtual DOM 渲染成瀏覽器真實(shí)的 DOM.

理解生命周期

掛載階段
組件也是有生命的, 如果一個(gè)組件被渲染到了頁面, 那么這個(gè)組件的生命便開始了.

也就是 Virtual DOM 變成真實(shí) DOM的這個(gè)過程. 組件生命的開始也叫組件的掛載.

上代碼:

import React from 'react';
import ReactDOM from 'react-dom';

class A extends React.Component {

  render(){
    return (
      <div>
        <p> 數(shù)字: 999 </p>
        <button>click once</button>
      </div>
    )
  }
}

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

<A/> 開始的時(shí)候還只是一份虛擬dom, 可一旦把它渲染到瀏覽器, 我們便說這個(gè)組件被掛載了.

更新階段
說白了就是 setState 導(dǎo)致 React.js 重新渲染組件并且把組件的變化應(yīng)用到 DOM 元素上的過程,這是一個(gè)組件的變化過程。

一個(gè)被掛載的組件, 某些時(shí)候可能會(huì)變化, 也就是被更新:

class A extends React.Component {

  constructor(props){
    super(props);

    this.state = {
      num: Math.random().toString().slice(2, 8)
    };
  }

  changeNum=()=>{
    this.setState({
      num: Math.random().toString().slice(2, 8)
    });
  }

  render(){

    let {num} = this.state;

    return (
      <div>
        <p> 數(shù)字: {num} </p>
        <button
          onClick={this.changeNum}
        >click once</button>
      </div>
    )
  }
}

我們改造下 A 組件. 每次點(diǎn)擊按鈕, 數(shù)字就會(huì)改變. 也就是這個(gè)組件會(huì)變化, 這個(gè)時(shí)候, 我們就說這個(gè)組件被更新了.

卸載階段 當(dāng)一個(gè)已經(jīng)被掛載的組件從頁面刪除掉, 那么這個(gè)組件實(shí)例的生命就結(jié)束了. 我們就說這個(gè)組件被卸載了.

我們改一下上面的代碼:

class B extends React.Component{

  render(){
    return (
      <div>我是組件 B</div>
    )
  }
}

class A extends React.Component {

  constructor(props){
    super(props);

    this.state = {
      isShowB: true
    };
  }

  changeNum=()=>{
    this.setState({
      isShowB: !this.state.isShowB
    });
  }

  render(){

    let {isShowB} = this.state;

    return (
      <div>
        {
          isShowB ? (
            <B/>
          ) : (
            <p>我不是B</p>
          )
        }
        <button
          onClick={this.changeNum}
        >click once</button>
      </div>
    )
  }
}

在第一次點(diǎn)擊按鈕之前, 有一個(gè) B 組件的實(shí)例被掛載到頁面, 而點(diǎn)擊按鈕之后, 這個(gè) B 組件實(shí)例就會(huì)被卸載掉.

重復(fù)的點(diǎn)擊按鈕, 就會(huì)不斷有新的 B 組件實(shí)例被掛載, 然后被卸載.

生命周期函數(shù)

無論是組件掛載, 更新, 還是卸載. 都是一個(gè)瞬間的事情. 但是在這個(gè)瞬間執(zhí)行之前和之后, React 會(huì)調(diào)用一些函數(shù), 我們把這些函數(shù)叫做生命周期函數(shù).

Mounting(掛載) 階段

    • 組件掛載時(shí)首先執(zhí)行
    • 在這里可以:
      • 初始化 state
      • 給事件函數(shù)綁定 this
  • componentWillMount()
    • 組件將要掛載時(shí)執(zhí)行
  • render()
    • 返回此刻組件的 JSX 結(jié)構(gòu)
  • componentDidMount()
    • 組件掛載完成后執(zhí)行
    • 在這里可以:
      • 開啟定時(shí)器
      • 發(fā)起請(qǐng)求
      • 訪問真實(shí)的 DOM 元素

這些函數(shù)是組件掛載階段執(zhí)行的函數(shù).

因?yàn)橐粋€(gè)組件實(shí)例只能被出生一次, 也就是一生只能被掛載一次, 所以這些函數(shù)在這個(gè)組件實(shí)例的生命周期中只會(huì)執(zhí)行一次.

當(dāng)然, render() 函數(shù)是個(gè)例外. 在掛載階段它需要返回 JSX 結(jié)構(gòu), 在更新階段, 它也需要返回新的 JSX 結(jié)構(gòu). 所以 render()可能會(huì)執(zhí)行多次.

Updateing(更新) 階段

  • componentWillReceiveProps( nextProps )
    • 父組件更新的時(shí)候執(zhí)行
  • shouldComponentUpdate( nextProps, nextState )
    • 返回 bool 值, 默認(rèn)返回 true
    • 如果返回 false, 當(dāng)前組件不會(huì)更新, 之后的生命周期函數(shù)不執(zhí)行
    • 性能優(yōu)化的主要手段之一
 // 更新前執(zhí)行的,所以在沒有更新之前
    shouldComponentUpdate(nP,nS){
        return !this.props.content === nP.content
    }
  • componentWillUpdate( nextProps, nextState )
    • 組件將要更新時(shí)執(zhí)行
  • render()
  • componentDidUpdate( prevProps, prevState )
    • 組件更新之后執(zhí)行

Unmounting(卸載) 階段

  • componentWillUnmount()
    • 組件將要卸載的時(shí)候執(zhí)行
      • 可以在這里:
        • 移除事件綁定
        • 清空定時(shí)器
        • 取消請(qǐng)求

很長一段時(shí)間, 組件的生命周期就是 掛載, 更新, 卸載三個(gè)階段.

在更新到了 16.0.0 之后, 新增了一個(gè) 錯(cuò)誤處理的階段.

新增了一個(gè)函數(shù):

  • componentDidCatch( error, info )

當(dāng)子組件的生命周期函數(shù)(包括 render(), constructor()和其他生命周期函數(shù))里面拋出了錯(cuò)誤, 那么這個(gè)函數(shù)就會(huì)執(zhí)行.

注意, 在此組件之下的子組件發(fā)生錯(cuò)誤的時(shí)候才會(huì)執(zhí)行, 組件自身的生命周期函數(shù)發(fā)生錯(cuò)誤不會(huì)捕獲到.

關(guān)于生命周期函數(shù)

在上面我們初步了解了組件的生命周期函數(shù), 并且我在每個(gè)生命周期函數(shù)的下面做了簡單的說明.

現(xiàn)在我們只要知道生命周期函數(shù)會(huì)在什么之后執(zhí)行就可以了.

有些生命周期會(huì)頻繁使用, 而有些則會(huì)很少用到.

關(guān)于如何生命周期函數(shù)在什么時(shí)候用這種問題, 這需要隨著時(shí)間, 隨著你解決各種業(yè)務(wù)需求之后, 會(huì)慢慢越來越有體會(huì).

現(xiàn)在, 你還不需要太關(guān)心這方面的問題.
image.png

屏幕快照 2018-06-25 上午3.04.28.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 說在前面 關(guān)于 react 的總結(jié)過去半年就一直碎碎念著要搞起來,各(wo)種(tai)原(lan)因(le)。心...
    陳嘻嘻啊閱讀 7,032評(píng)論 7 41
  • 生命周期流程圖簡單如下: 組件讓你把用戶界面分成獨(dú)立的,可重復(fù)使用的部分,并且將每個(gè)部分分開考慮。React.Co...
    Simple_Learn閱讀 1,189評(píng)論 0 0
  • 了解React生命周期,對(duì)我們理解React的工作過程很有幫助。所有的事物都有自己的生命過程,React組件也不例...
    Srtian閱讀 279評(píng)論 0 0
  • part1 最近的工作狀態(tài)還是比較不錯(cuò)的,很能明顯的感受到自己這一個(gè)月成長的很快。 很喜歡這種不注重人際關(guān)系的氛圍...
    安_1116閱讀 328評(píng)論 0 0
  • 清早悠悠轉(zhuǎn)醒,忽然發(fā)覺已經(jīng)到四月末 了。我想著還是出去走走,抓住四月的尾巴也是好的。 林徽因有詩——《你是人間的四...
    山非南山閱讀 588評(píng)論 0 2

友情鏈接更多精彩內(nèi)容