React生命周期

又是一個(gè)老生常談的內(nèi)容,從ES6起已經(jīng)開(kāi)始使用class的方式去創(chuàng)建組件,這種創(chuàng)建方式上的變化也帶來(lái)了寫法和方法上的改變,做一個(gè)總結(jié)

1.創(chuàng)建組件的差異

ES6之前采用React.createClass()的方式去創(chuàng)建組件,所有跟生命周期相關(guān)的方法都以一個(gè)json的都放到對(duì)應(yīng)的小括號(hào)里,作為參數(shù),作為初始值

var Hello = React.createClass({
    componentWillMount:function () {
        console.log("我將要被加載出來(lái)");
    },
   render:function () {
        console.log("渲染");
        return <div>我被渲染出來(lái)了</div>;
   },
  componentDidMount:function () {
        console.log("已經(jīng)加載完成");
  }
})

ES6之后,JS也開(kāi)始有了class,所以寫法上就有了很大的變化

import React, { Component } from 'react';

class Counter extends Component {
    constructor(props) {
        super(props);
    }
    componentWillReceiveProps(nextProps) {
        console.log('enter componentWillReceiveProps ' + this.props.caption)
    }
    componentWillMount() {
        console.log('enter componentWillMount ' + this.props.caption);
    }
}

首先在第一行引入react包文件,Component相當(dāng)于組件類的父類,只要?jiǎng)?chuàng)建組件就要繼承于這個(gè)父類,而且第一個(gè)React即使沒(méi)用上,也一定要寫,否則編譯不過(guò),第一個(gè)寫的是父類的構(gòu)造函數(shù),也就是說(shuō),因?yàn)閷懛ㄉ系牟煌?生命周期的函數(shù),也發(fā)生了變化

2.裝載過(guò)程 Mount

1.constructor
構(gòu)造函數(shù),當(dāng)然創(chuàng)建的時(shí)候也可以不寫,寫構(gòu)造函數(shù)兩種情況

1.綁定this,在ES6中每個(gè)成員在執(zhí)行時(shí),this并不是跟對(duì)象自動(dòng)綁定,所以為了方便使用,在構(gòu)造函數(shù)就將這個(gè)對(duì)象和this綁定好
2.初始化state,因?yàn)槭堑谝粋€(gè)執(zhí)行的生命周期函數(shù),所以在構(gòu)造函數(shù)初始化state最合適,也方便在其他過(guò)程使用state

而且在構(gòu)造函數(shù)的第一句,一定要寫super(props);不寫編譯不通過(guò).

2.getInitialState和getDefaultProps
getInitialState這個(gè)函數(shù)的作用會(huì)返回初始化組件的this.state,getDefaultProps的作用就是返回this.props,但是這兩個(gè)方法是配合React.createClass這種創(chuàng)建使用的,也就是說(shuō)ES6之后,這兩個(gè)方法就不能使用了,如果非常倔強(qiáng),就是要用,不影響編譯,但是在控制臺(tái)會(huì)有一個(gè)紅色warning

警告

3.render
這個(gè)函數(shù)的地位毋庸置疑,非常重要,哪怕別的周期函數(shù)不寫,這個(gè)也一定要寫,因?yàn)楦割悓?duì)除render之外的函數(shù)都默認(rèn)實(shí)現(xiàn).render要對(duì)應(yīng)的是一個(gè)純函數(shù),它返回一個(gè)JSX描述的結(jié)構(gòu),最終通過(guò)React來(lái)完成渲染工作.

4.componentWillMount和componentDidMount
componentWillMount是優(yōu)先于render執(zhí)行的,在渲染之前之前執(zhí)行,如果想在這個(gè)函數(shù)寫點(diǎn)什么的話,那些代碼可以都移位到構(gòu)造函數(shù)中去寫,這個(gè)函數(shù)也可以認(rèn)為是相對(duì)componentDidMount存在的,用處也大,就是將要裝載這樣一個(gè)狀態(tài).
componentDidMount這個(gè)函數(shù)是在render之后調(diào)用,但是當(dāng)一個(gè)組件由多個(gè)子組件組成的時(shí)候,執(zhí)行順序會(huì)發(fā)生些許變化


執(zhí)行順序

三個(gè)組件的componentDidMount方法并沒(méi)有在各自組件render方法之后執(zhí)行,而是都最后一步統(tǒng)一執(zhí)行,這是因?yàn)閞ender只是返回一個(gè)結(jié)構(gòu)的描述,最終是靠React來(lái)完成渲染工作,所以React完成三個(gè)組件的轉(zhuǎn)載之后,才算完成整個(gè)裝載,才會(huì)調(diào)用componentDidMount這個(gè)函數(shù),所以都在最后一起調(diào)用.而且這個(gè)函數(shù)調(diào)用的時(shí)候能保證Dom樹(shù)已經(jīng)全部加載出來(lái)了,也可以在這個(gè)函數(shù)里使用Ajax進(jìn)行網(wǎng)絡(luò)請(qǐng)求,去做一些邏輯上的操作
整體下來(lái)裝載過(guò)程的生命周期函數(shù)執(zhí)行順序
constructor-> componentWillMount -> render -> componentDidMount

3.更新過(guò)程 Update

第一個(gè)大過(guò)程是組件被裝載到Dom上用戶對(duì)組件的第一印象的過(guò)程,但是在程序執(zhí)行的過(guò)程中,props和state可能隨時(shí)會(huì)發(fā)生變化,所以在過(guò)程中會(huì)一直處于一個(gè)更新的過(guò)程.這個(gè)過(guò)程有五個(gè)周期函數(shù)

1.componentWillReceiveProps(newProps)
這個(gè)函數(shù)的作用是當(dāng)父組件render被調(diào)用,對(duì)應(yīng)的子組件也會(huì)發(fā)生更新過(guò)程,不管這個(gè)過(guò)程中父組件傳給子組件的props有沒(méi)有發(fā)生變化,都會(huì)觸發(fā)子組件的componentWillReceiveProps,也就是這個(gè)方法實(shí)際上是在子組件被調(diào)用的,而且會(huì)把新的props傳給子組件,newProps就是對(duì)應(yīng)的參數(shù).這個(gè)方法是props更新會(huì)觸發(fā),this.state不會(huì)觸發(fā)調(diào)動(dòng)這個(gè)方法.最簡(jiǎn)單的方式就是父組件有一個(gè)按鈕,調(diào)用this.forceUpdate,強(qiáng)制讓React組件重新繪制,類似初始化

// 父組件
<Son caption="First" initValue={20} />
<button onClick={() => this.forceUpdate()}></button>
// 子組件
componentWillReceiveProps(newProps) {
  console.log(newProps);
  console.log('componentWillReceiveProps ' + this.props.initValue)
}

只要觸發(fā)重新繪制就能觸發(fā),方法不唯一

2.shouldComponentUpdate(nextProps, nextState)
render函數(shù)通過(guò)JSX告訴React需要渲染什么,shouldComponentUpdate的作用就是與之相反,告訴React哪些內(nèi)容不需要渲染.這個(gè)函數(shù)也和render一樣,需要一個(gè)返回值,但是這個(gè)返回值類型是bool,通過(guò)True和False告訴React在這次更新過(guò)程中,組件是夠需要更新,重新渲染.靈活使用這個(gè)函數(shù),可以大大的提高React的性能.

// 子組件
shouldComponentUpdate(newProps, newState) {
    return (newProps.caption !== this.props.caption) ||
           (newState.count !== this.state.count);
}

當(dāng)子組件要渲染之前,會(huì)觸發(fā)這個(gè)函數(shù),會(huì)把當(dāng)前新的props和新的state作為兩參數(shù)傳到函數(shù)里,當(dāng)然如果直接返回false,無(wú)論怎么樣都不會(huì)重新繪制了,所以可以根據(jù)值的變化進(jìn)行選擇性的繪制.而且在使用this.setState的時(shí)候,并不是第一時(shí)間更新組件組件上state相關(guān)的值,在執(zhí)行shouldComponentUpdate的時(shí)候this.state還是原來(lái)的值,并沒(méi)有發(fā)生變化,所以需要四個(gè)值都進(jìn)行比較.

3.componentWillUpdate和componentDidUpdate
當(dāng)上一步shouldComponentUpdate通過(guò)之后,會(huì)調(diào)用componentWillUpdate,render和componentDidUpdate,這兩個(gè)函數(shù)也會(huì)把render加在中間,作用跟componentWillMount和componentDidMount差不多,就不在贅述了
更新過(guò)程的生命周期執(zhí)行順序大致如下
componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate

4.卸載過(guò)程 Unmount

這個(gè)周期下只涉及到1個(gè)函數(shù)componentWillUnmount,當(dāng)React組件要從Dom樹(shù)上移除的時(shí)候會(huì)觸發(fā)這個(gè)函數(shù),做組件的收尾工作.
如果在開(kāi)始的時(shí)候使用componentDidMount創(chuàng)建了一些非React的方法創(chuàng)建的DOM元素,,就需要在卸載過(guò)程中,對(duì)這部分內(nèi)容進(jìn)行清除,防止造成不必要的內(nèi)存問(wèn)題

大將南征膽氣豪,腰橫秋水雁翎刀。
風(fēng)吹鼉鼓山河動(dòng),電閃旌旗日月高。
天上麒麟原有種,穴中螻蟻豈能逃。
太平待詔歸來(lái)日,朕與先生解戰(zhàn)袍

最后編輯于
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 組件的生命周期方法分以下三個(gè)階段。 Mounting當(dāng)創(chuàng)建組件的實(shí)例并將其插入到DOM中時(shí),將調(diào)用這些方法:con...
    _八神光_閱讀 1,221評(píng)論 0 0
  • 譯自 React Component Lifecycle 每個(gè)組件都有若干生命周期函數(shù)。如函數(shù)名稱所示,帶有wil...
    KrisLeeSH閱讀 643評(píng)論 0 0
  • 組件的生命周期 組件會(huì)經(jīng)過(guò)三個(gè)過(guò)程: 裝載過(guò)程(Mount),也就是把組件愛(ài)你第一次在DOM樹(shù)中渲染的過(guò)程; 更新...
    Kris_lee閱讀 544評(píng)論 0 1
  • 好比我們?nèi)顺硕虝旱纳c死那一瞬之外,生命中剩下的時(shí)間都用在了每天活著的狀態(tài),對(duì)于React中的組件來(lái)講,占其總生...
    YeLqgd閱讀 10,660評(píng)論 0 7
  • React生命周期主要經(jīng)歷四個(gè)階段:創(chuàng)建階段,實(shí)例化階段,和更新階段。 創(chuàng)建階段 主要發(fā)生在創(chuàng)建組件類時(shí),即調(diào)用R...
    葶寳寳閱讀 656評(píng)論 2 5

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