React 嵌套組件樹生命周期

? ? ? ? 要講React的生命周期的話,網(wǎng)上講的已經(jīng)很過了,不過大多數(shù)是講react單個組件的生命周期,理論上組件本質(zhì)是狀態(tài),生命周期大致分為三個階段,大致流程如下:

一、初始化階段

getDefaultProps:獲取實(shí)例的默認(rèn)屬性(即使沒有生成實(shí)例,組件的第一個實(shí)例被初始化createClass的時候調(diào)用,只調(diào)用一次)

?getInitialState:獲取每個實(shí)例的初始化狀態(tài)(每個實(shí)例自己維護(hù))

?componentWillMount:組件即將被裝載、渲染到頁面上,即組件掛載之前調(diào)用一次,如果在這個函數(shù)中調(diào)用setState,本次的render函數(shù)可以看到更新后的state,并且只渲染一次 render:組件在這里生成虛擬的DOM節(jié)點(diǎn)(只能訪問this.props和this.state,只有一個頂層組件,render返回值只能是一個組件,不允許修改狀態(tài)和DOM輸出)?

componentDidMount:在組件掛載之后調(diào)用一次,這個時候子組件也都掛載好了,可以在這里使用refs。組件真正在被裝載之后可以修改DOM

二、運(yùn)行中狀態(tài)

componentWillReceiveProps(nextProps):當(dāng)組件props改變的時候,組件將要接收到新的屬性的時候調(diào)用。props是父組件傳遞給子組件的,父組件發(fā)生render的時候子組件就會調(diào)用這個方法,不管props有沒有更新,也不管父子組件之間有沒有數(shù)據(jù)交換。

?shouldComponentUpdate(nextProps,nextState):當(dāng)組件數(shù)據(jù)(props)或者狀態(tài)(state)改變的時候調(diào)用,組件掛載之后,每次調(diào)用setState后都會調(diào)用shouldComponentUpdate判斷是否需要重新渲染組件。默認(rèn)返回true,需要重新render。在比較復(fù)雜的應(yīng)用里,有一些數(shù)據(jù)的改變并不影響界面顯示,可以在這里做判斷,優(yōu)化渲染效率。?

componentWillUpdate(nextProps,nextState):這個是shouldComponentUpdate方法返回true的時候或者調(diào)用forceUpdate之后調(diào)用。這時候不能修改屬性和狀態(tài) render:只能訪問this.props和this.state,只有一個頂層組件,render返回值只能是一個組件,不允許修改狀態(tài)和DOM輸出

componentDidUpdate:除了首次render之后調(diào)用componentDidMount,其他render結(jié)束之后都是調(diào)用componentDidUpdate

三、銷毀階段

componentWillUnmount:開發(fā)者需要來銷毀(組件真正刪除之前調(diào)用,比如銷毀計時器和事件監(jiān)聽器)

下面是從官網(wǎng)上找到的一張流程圖,把上面的步驟描述的非常詳細(xì)了。

對于一個工程來說,一般是多個組件組成的組件樹,因此弄清楚組件嵌套在一起的組件樹的生命周期,無論是對于項目優(yōu)化還是對于項目的運(yùn)行過程的把控都是很重要的。下面研究一下,一個示例

//父組件

class Parent extends PureComponent {

? ? constructor(props) {

? ? ? ? super(props);

? ? ? ? console.log('Parent constructor');

? ? }

? ? componentWillMount() {

? ? ? ? console.log('Parent componentWillMount');

? ? }

? ? render() {

? ? ? ? console.log('RootContainer render');

? ? ? ? return (

? ? ? ? ? ? <div className="root">

? ? ? ? ? ? ? ? <h3>This is Parent</h3>

? ? ? ? ? ? ? ? <Child/>

? ? ? ? ? ? </div>

? ? ? ? );

? ? }

? ? componentDidMount() {

? ? ? ? console.log('Parent componentDidMount');

? ? }

? ? componentWillUnmount() {

? ? ? ? console.log('Parent componentWillUnmount');

? ? }

? ? componentWillReceiveProps(nextProps) {

? ? ? ? console.log('Parent componentWillReceiveProps(nextProps)');

? ? }

? ? componentWillUpdate(nextProps, nextState) {

? ? ? ? console.log('Parent componentWillUpdate(nextProps, nextState)');

? ? }

? ? shouldComponentUpdate(nextProps, nextState) {

? ? ? ? console.log('Parent shouldComponentUpdate(nextProps, nextState)');

? ? ? ? return true;

? ? }

? ? componentDidUpdate(prevProps, prevState) {

? ? ? ? console.log('Parent componentDidUpdate(prevProps, prevState)');

? ? }

}

//子組件

class Child extends PureComponent {

? ? constructor(props) {

? ? ? ? super(props);

? ? ? ? console.log('Child constructor');

? ? }

? ? componentWillMount() {

? ? ? ? console.log('Child componentWillMount');

? ? }

? ? render() {

? ? ? ? console.log('Child render');

? ? ? ? return (

? ? ? ? ? ? <div className="child">

? ? ? ? ? ? ? ? <h4>I am a Child</h4>

? ? ? ? ? ? </div>

? ? ? ? );

? ? }

? ? componentDidMount() {

? ? ? ? console.log('Child componentDidMount');

? ? }

? ? componentWillUnmount() {

? ? ? ? console.log('Child componentWillUnmount');

? ? }

? ? componentWillReceiveProps(nextProps) {

? ? ? ? console.log('Child componentWillReceiveProps(nextProps)');

? ? }

? ? shouldComponentUpdate(nextProps, nextState) {

? ? ? ? console.log('ChildView shouldComponentUpdate(nextProps, nextState)');

? ? ? ? return true;

? ? }

? ? componentWillUpdate(nextProps, nextState) {

? ? ? ? console.log('Child componentWillUpdate(nextProps, nextState)');

? ? }

? ? componentDidUpdate(prevProps, prevState) {

? ? ? ? console.log('Child componetDidUpdate(prevProps, prevState)');

? ? }

}

運(yùn)行后結(jié)果如下:

Parent constructor

Parent componentWillMount

Parent render

Child constructor

Child componentWillMount

Child render

Child componentDidMount

Parent componentDidMount

此時可以分析出,當(dāng)父組建?render?時遇到子組件,然后進(jìn)入子組件的生命周期,當(dāng)執(zhí)行完子組件生命周期中的componentDidMount?時會回到父組建繼續(xù)執(zhí)行父組建未完成的生命周期。

由上面父子嵌套組件的生命周期流程,可以推斷繼續(xù)驗(yàn)證多級組件嵌套的流程,

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

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

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