react入門系列之react生命周期函數(shù)

什么是生命周期函數(shù)

  1. 組件中在某個階段會自動執(zhí)行的函數(shù)。
    • 比如我們執(zhí)行使用render函數(shù),在prop或者state變化時,render函數(shù)自動執(zhí)行。
    • 因此render函數(shù)就是一個生命周期函數(shù)。
  2. constructor在組件創(chuàng)建的時候也會自動調(diào)用。但是他不是react獨有,是es6中的函數(shù)所以,我們不將他列為生命周期函數(shù)。

生命周期分為4個階段

  1. initialization(組件初始化)
    • 我們在創(chuàng)建組件的時候需要繼承react Component這個基類,也就繼承這個react的基類,才能有render(),生命周期等方法可以使用,這也說明為什么函數(shù)組件不能使用這些方法的原因。同時也讓組件能使用setState方法。
    • 然后我們在 constructor 構(gòu)造函數(shù)中使用 super(props)來將父組件傳遞的props注入給這個組件,以及使用this.state初始化這個組件的屬性。
    • 這一系列動作就是組件的初始化。
  2. mount (組件的掛載)
    • 此階段分為三個時期
      1. componentWillMount(掛載之前)

        • 這個函數(shù)在組件掛載到DOM之前的時候執(zhí)行,所以你在這里引用setState方法,是不會引起組件的重新渲染。
        • 同樣這里做的事情如果放在constructor構(gòu)造函數(shù)中去使用也是可以的。
        • 這個函數(shù)只會被調(diào)用一次,就是組件掛載到DOM之前的時候。其他時候是不會觸發(fā)這個函數(shù)的。
      2. render(掛載中)

        • 根據(jù)組件的props和state是否變化,變化即執(zhí)行,這里的變化要注意,并不是值變化。只要重新賦值,新舊值相同也會執(zhí)行。
        • 然后return 一個React元素(描述組件,即UI),不負(fù)責(zé)組件實際渲染工作,之后由React自身根據(jù)此元素去渲染出頁面DOM。render是純函數(shù)(Pure function:函數(shù)的返回結(jié)果只依賴于它的參數(shù);函數(shù)執(zhí)行過程里面沒有副作用。
        • 不能在里面執(zhí)行this.setState,會有改變組件狀態(tài)的副作用。
      3. componentDidMount(掛載完成)

        • 約定將ajax請求放在這個生命周期函數(shù)中
        • 組件掛載到DOM后被執(zhí)行,只會執(zhí)行一次。
  3. update (組件更新時)
    • 首先我們來了解一下什么時組件更新。只有在通過setState函數(shù)使sate和props變化或重新賦值時才叫組件更新。

    • setState引起父組件的render函數(shù)執(zhí)行,同時也會引起它的子組件的render函數(shù)執(zhí)行。

    • 原因是react虛擬DOM的diff算法,同級比較原理。

    • 只要重新賦值就是組件更新,如果值并沒有變,也更新組件,這樣就會耗性能,也是我們講同級比較的時候說的一個弊端。

    • 接下來我們了解一下有那些周期函數(shù)

      1. componentWillReceiveProps(nextProps)

        • 此方法只調(diào)用于props引起的組件更新過程中,參數(shù)nextProps是父組件傳給當(dāng)前組件的新props。但父組件render方法的調(diào)用不能保證重傳給當(dāng)前組件的props是有變化的,所以在此方法中根據(jù)nextProps和this.props來查明重傳的props是否改變,以及如果改變了要執(zhí)行啥,比如根據(jù)新的props調(diào)用this.setState出發(fā)當(dāng)前組件的重新render
      2. shouldComponentUpdate(nextProps, nextState)

        • 此方法通過比較nextProps,nextState及當(dāng)前組件的this.props,this.state,返回true時當(dāng)前組件將繼續(xù)執(zhí)行更新過程,返回false則當(dāng)前組件更新停止,以此可用來減少組件的不必要渲染,優(yōu)化組件性能。ps:這邊也可以看出,就算componentWillReceiveProps()中執(zhí)行了this.setState,更新了state,但在render前(如shouldComponentUpdate,componentWillUpdate),this.state依然指向更新前的state,不然nextState及當(dāng)前組件的this.state的對比就一直是true了。
      3. componentWillUpdate(nextProps, nextState)

        • 此方法在調(diào)用render方法前執(zhí)行,在這邊可執(zhí)行一些組件更新發(fā)生前的工作,一般較少用。
      4. render

        • render方法在上文講過,這邊只是重新調(diào)用。
      5. componentDidUpdate(prevProps, prevState)

        • 此方法在組件更新后被調(diào)用,可以操作組件更新的DOM,prevProps和prevState這兩個參數(shù)指的是組件更新前的props和state
  • 優(yōu)化弊端
  • 1.當(dāng)因為父組件重新render,使得props重新被賦值,導(dǎo)致子組件跟著渲染.
/**
 * 方法一:解決上述弊端,可以在shouldComponentUpdate函數(shù),組件更新前進(jìn)行判斷,props是否改變,再確定是否執(zhí)行重新渲染。
*/
class Child extends Component {
   shouldComponentUpdate(nextProps){ 
        if(nextProps.value === this.props.value){
          return false
        }
        return true
    }
    render() {
        return <div>{this.props.value}</div>
    }
}
/**
 * 方法二:
 * 1.解決上述弊端,也可以先將this.props.value賦值給子組件的state
 * 2.再在componentWillReceiveProps函數(shù)中,使用setState去重新給stae中的屬性賦值this.props.value
 * 3.文檔中提到,在該函數(shù)(componentWillReceiveProps)中調(diào)用 this.setState() 將不會引起第二次渲染。
 * 4.因為componentWillReceiveProps是在props有變化的時候才會觸發(fā),所以在這里面做this.setState()一定是有改變state
*/
//
class Child extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: props.value // 先將this.props.value賦值給子組件的state
        };
    }
    componentWillReceiveProps(nextProps) { // 在props有變化的時候才會觸發(fā)這個方法
        this.setState({value: nextProps.value}); // 重新賦值,引起render
    }
    render() {
        return <div>{this.state.value}</div>
    }
}
  • 2.組件本身調(diào)用setState方法,但是并沒有改變state中的值。
/**
 * 也是通過shouldComponentUpdate判斷新舊值是否改變,改變才做render
*/
class Test extends Component {
   constructor(props) {
        super(props);
        this.state = {
          value:1
        }
   }
   shouldComponentUpdate(nextState){ // 應(yīng)該使用這個方法判斷新舊值是否改變
        if(nextState.value === this.state.value){
          return false // 沒有改變返回false
        }
        return true
    }

   changeState = () => { // 雖然調(diào)用了setState ,但state并無變化
        const value = this.state.value
         this.setState({
            value
         })
   }

    render() {
        return <div onClick = {this.changeState}>{this.state.value}</div>
    }
}

  1. 卸載階段(componentWillUnmount)
  • 只有一個生命周期方法componentWillUnmount
    • 此方法在組件被卸載前調(diào)用,可以在這里執(zhí)行一些清理工作,比如清楚組件中使用的定時器,清楚componentDidMount中手動創(chuàng)建的DOM元素等,以避免引起內(nèi)存泄漏。
  1. 在react組件中,除了render函數(shù),其他任何生命周期函數(shù)都可以不寫,因為組件繼承了react中的 Component,Component內(nèi)置了其他的生命周期函數(shù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 作為一個合格的開發(fā)者,不要只滿足于編寫了可以運行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個周閱讀 8,675評論 1 33
  • 40、React 什么是React?React 是一個用于構(gòu)建用戶界面的框架(采用的是MVC模式):集中處理VIE...
    萌妹撒閱讀 1,184評論 0 1
  • 生命周期流程圖簡單如下: 組件讓你把用戶界面分成獨立的,可重復(fù)使用的部分,并且將每個部分分開考慮。React.Co...
    Simple_Learn閱讀 1,189評論 0 0
  • React 生命周期很多人都了解,但通常我們所了解的都是單個組件的生命周期,但針對Hooks 組件、多個關(guān)聯(lián)組件(...
    前端js閱讀 7,288評論 3 7
  • 起步 安裝官方腳手架: npm install -g create-react-app 創(chuàng)建項目: create-...
    Twoold閱讀 1,554評論 0 0

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