React和Angular都具有生命周期慰毅,他們的生命周期分別時(shí)什么樣的?二者生命周期間又有沒有什么共同點(diǎn)呢嗅虏,我們可以一起探討一下洛姑。
1、React的生命周期
React的生命周期主要分為兩個(gè)版本(以16.4版本劃分)皮服,為了更好理解楞艾,我們將兩個(gè)版本分為“初始版本”和“更新版本”。下面我們將首先介紹React “初始版本”的生命周期龄广。
1.1 React “初始版本”的生命周期硫眯。
React “初始版本”的生命周期方法主要有以下幾種,他們的簡(jiǎn)要定義如下:
? constructor:完成了React數(shù)據(jù)的初始化
? componentWillMount:在掛載之前被調(diào)用择同。它在 render() 之前調(diào)用两入,因此在此方法中同步調(diào)用 setState() 不會(huì)觸發(fā)額外渲染。
? componentDidMount:會(huì)在組件掛載后(插入 DOM 樹中)立即調(diào)用奠衔。依賴于 DOM 節(jié)點(diǎn)的初始化應(yīng)該放在這里谆刨。返回?cái)?shù)據(jù)setState后組件會(huì)重新渲染
? shouldComponentUpdate(nextProps,nextState):當(dāng) props 或 state 發(fā)生變化時(shí)塘娶,shouldComponentUpdate會(huì)在渲染執(zhí)行之前被調(diào)用归斤。返回值默認(rèn)為 true。首次渲染或使用forceUpdate時(shí)不會(huì)調(diào)用該方法刁岸。如果shouldComponentUpdate返回false脏里,則不會(huì)調(diào)用componentWillUpdate,render和componentDidUpdate虹曙。
? componentWillUpdate (nextProps,nextState):當(dāng)組件收到新的props或state時(shí)迫横,且shouldComponentUpdate返回true,會(huì)在渲染之前調(diào)用該方法酝碳。使用此作為在更新發(fā)生之前執(zhí)行準(zhǔn)備更新的機(jī)會(huì)矾踱。初始渲染不會(huì)調(diào)用此方法。
? componentDidUpdate(prevProps,prevState):會(huì)在更新后會(huì)被立即調(diào)用疏哗。首次渲染不會(huì)執(zhí)行此方法呛讲。
? render: 會(huì)插入jsx生成的dom結(jié)構(gòu),生成一份虛擬dom樹返奉,在每一次組件更新時(shí)贝搁,react會(huì)比較更新前后的新舊DOM樹,然后找到最小的有差異的DOM節(jié)點(diǎn)芽偏,進(jìn)行重新渲染雷逆。
? componentWillReceiveProps:會(huì)在已掛載的組件接收新的props之前被調(diào)用。如果你需要更新狀態(tài)以響應(yīng)prop更改(例如污尉,重置它)膀哲,你可以比較this.props和nextProps往产,將nextProps的state為當(dāng)前組件的state,從而重新渲染組件.
? componentWillUnmount:會(huì)在組件卸載及銷毀之前直接調(diào)用某宪。在此方法中執(zhí)行必要的清理操作捂齐,例如,清除timer缩抡,取消網(wǎng)絡(luò)請(qǐng)求或清除在componentDidMount中創(chuàng)建的訂閱等奠宜。
為了更好理解下面將結(jié)合demo,進(jìn)行查看瞻想,實(shí)例demo鏈接如下:
https://codesandbox.io/s/nostalgic-fermat-8t67h?file=/src/App.js
結(jié)合代碼压真,我們可以查看生命周期函數(shù)的執(zhí)行順序。
當(dāng)頁面初始渲染時(shí)蘑险,我們可以發(fā)現(xiàn)生命周期函數(shù)的執(zhí)行順序如下:
通過“點(diǎn)擊+1”更新state后滴肿,生命周期函數(shù)的執(zhí)行順序如下:
修改代碼后,生命周期函數(shù)的執(zhí)行順序如下:
<button onClick={this.handleClick}>點(diǎn)擊加1佃迄!</button>
從上述流程泼差,我們可以發(fā)現(xiàn)React生命周期如下圖所示,主要可以分為三個(gè)過程:
? 掛載過程(深藍(lán)部分): 該部分包含constract(初始化)呵俏、 componentWillMount堆缘、 render、componentDidMount普碎。
? 更新過程(淺藍(lán)色部分): 該部分包括componentWillReceiveProps(該方法在demo中未展示) 吼肥、shouldComponentUpdate、 componentWillUpdate麻车、render缀皱、componentWillUpdate
? 銷毀階段(橙色部分):該部分包括componentWillUnmount
1.2 React “更新版本”的生命周期
React16.4后使用了新的生命周期,具體使用getDerivedStateFromProps代替了舊的componentWillReceiveProps及componentWillMount动猬。使用getSnapshotBeforeUpdate代替了舊的componentWillUpdate啤斗。其余的保持不變。
? getDerivedStateFromProps:會(huì)在調(diào)用 render 方法之前調(diào)用赁咙,并且在初始掛載及后續(xù)更新時(shí)都會(huì)被調(diào)用钮莲。它應(yīng)返回一個(gè)對(duì)象來更新 state,如果返回null則不更新任何內(nèi)容序目。
? getSnapshotBeforeUpdate:該方法會(huì)在 render 之后臂痕, DOM 更新前被調(diào)用,用于讀取最新的 DOM 數(shù)據(jù)猿涨。此生命周期方法的任何返回值將作為 componentDidUpdate的第三個(gè)參數(shù)握童。
基于上述內(nèi)容,更改演示demo叛赚,演示結(jié)果如下:
由此可見澡绩,“更新版本”的生命周期如下圖所示:
1.3 React hooks的“生命周期”
React在16.8后引入了hooks稽揭,讓我們可以在不便攜class的情況下使用state以及其他的react特性。hooks相比與 class 的生命周期概念來說肥卡,它更接近于實(shí)現(xiàn)狀態(tài)同步溪掀,而不是響應(yīng)生命周期事件。我們可以利用useState步鉴、useMemo揪胃、useEffect、useLayoutEffect來模擬實(shí)現(xiàn)生命周期氛琢,對(duì)應(yīng)關(guān)系如下:
2喊递、Angular的生命周期
Anuglar組件的生命周期鉤子方法有以下八種,他們的用途和時(shí)機(jī)分別如下:
為了更好理解Angular的生命周期方法阳似,下面我們將結(jié)合demo進(jìn)行查看骚勘,
demo(下載范例)包含幾個(gè)示例,其中“Peek-A-Boo”展示每個(gè)生命周期方法撮奏,每個(gè)方法調(diào)用后都會(huì)在屏幕上顯示一條日志俏讹。
最開始,頁面為下圖所示:
點(diǎn)擊“Create PeekABooComponent”后, 子組件<peek-a-boo>內(nèi)容展示畜吊,此時(shí)泽疆,生命周期方法的調(diào)用順序?yàn)椋?/p>
點(diǎn)擊“Update Hero”后, 子組件<peek-a-boo>內(nèi)容更新,此時(shí)定拟,生命周期方法的調(diào)用順序?yàn)椋?/p>
點(diǎn)擊“Destroy PeekABooComponent”后, 子組件<peek-a-boo>消失于微,此時(shí)逗嫡,生命周期方法的調(diào)用順序?yàn)椋?/p>
基于上述demo青自,我們可以獲知Angular的生命周期可劃分為了三個(gè)階段,分別為:組件初始化階段驱证,變化檢測(cè)延窜,組件銷毀。
? 組件初始化階段:從ngOnChange開始抹锄,按照下圖的順序執(zhí)行逆瑞,直到ngAfterViewChecked;
? 變化檢測(cè)階段:主要由ngOnchange、ngDeCheck伙单、ngAfterContentChedked以及ngAfterViewChecked檢測(cè)获高;
? 組件銷毀階段:由ngOnDestory控制。
值得注意的是吻育,下圖紫色的都只會(huì)被調(diào)用一次念秧,綠色的可被調(diào)用多次。
此外布疼,AfterContent 鉤子和 AfterView 相似摊趾。關(guān)鍵的不同點(diǎn)是子組件的類型不同: AfterContent 所關(guān)心的是 ContentChildren币狠,這些子組件被 Angular 投影進(jìn)該組件中。AfterView 所關(guān)心的是 ViewChildren砾层,這些子組件的元素標(biāo)簽會(huì)出現(xiàn)在該組件的模板里面漩绵。
3、React和Angular生命周期的對(duì)比分析
React和Angular的生命周期差異性較大肛炮,我嘗試在二者生命周期間找到一些共性止吐,下面是我的一些發(fā)現(xiàn),可能不完全匹配侨糟,歡迎共同探討祟印。
4、結(jié)語
以上就是我對(duì)于React和Angular生命周期的一些理解啦粟害,如果有紕漏或錯(cuò)誤蕴忆,歡迎指出!
又是學(xué)習(xí)的一天悲幅,fighting~