- React進(jìn)階之路
- 徐超
- 1690字
- 2019-12-06 16:33:38
2.3 組件的生命周期
組件從被創(chuàng)建到被銷毀的過程稱為組件的生命周期。React為組件在不同的生命周期階段提供不同的生命周期方法,讓開發(fā)者可以在組件的生命周期過程中更好地控制組件的行為。通常,組件的生命周期可以被分為三個(gè)階段:掛載階段、更新階段、卸載階段。
2.3.1 掛載階段
這個(gè)階段組件被創(chuàng)建,執(zhí)行初始化,并被掛載到DOM中,完成組件的第一次渲染。依次調(diào)用的生命周期方法有:
(1)constructor
(2)componentWillMount
(3)render
(4)componentDidMount
1.constructor
這是ES 6 class的構(gòu)造方法,組件被創(chuàng)建時(shí),會(huì)首先調(diào)用組件的構(gòu)造方法。這個(gè)構(gòu)造方法接收一個(gè)props參數(shù),props是從父組件中傳入的屬性對(duì)象,如果父組件中沒有傳入屬性而組件自身定義了默認(rèn)屬性,那么這個(gè)props指向的就是組件的默認(rèn)屬性。你必須在這個(gè)方法中首先調(diào)用super(props)才能保證props被傳入組件中。constructor通常用于初始化組件的state以及綁定事件處理方法等工作。
2.componentWillMount
這個(gè)方法在組件被掛載到DOM前調(diào)用,且只會(huì)被調(diào)用一次。這個(gè)方法在實(shí)際項(xiàng)目中很少會(huì)用到,因?yàn)榭梢栽谠摲椒ㄖ袌?zhí)行的工作都可以提前到constructor中。在這個(gè)方法中調(diào)用this.setState不會(huì)引起組件的重新渲染。
3.render
這是定義組件時(shí)唯一必要的方法(組件的其他生命周期方法都可以省略)。在這個(gè)方法中,根據(jù)組件的props和state返回一個(gè)React元素,用于描述組件的UI,通常React元素使用JSX語法定義。需要注意的是,render并不負(fù)責(zé)組件的實(shí)際渲染工作,它只是返回一個(gè)UI的描述,真正的渲染出頁面DOM的工作由React自身負(fù)責(zé)。render是一個(gè)純函數(shù),在這個(gè)方法中不能執(zhí)行任何有副作用的操作,所以不能在render中調(diào)用this.setState,這會(huì)改變組件的狀態(tài)。
4.componentDidMount
在組件被掛載到DOM后調(diào)用,且只會(huì)被調(diào)用一次。這時(shí)候已經(jīng)可以獲取到DOM結(jié)構(gòu),因此依賴DOM節(jié)點(diǎn)的操作可以放到這個(gè)方法中。這個(gè)方法通常還會(huì)用于向服務(wù)器端請(qǐng)求數(shù)據(jù)。在這個(gè)方法中調(diào)用this.setState會(huì)引起組件的重新渲染。
2.3.2 更新階段
組件被掛載到DOM后,組件的props或state可以引起組件更新。props引起的組件更新,本質(zhì)上是由渲染該組件的父組件引起的,也就是當(dāng)父組件的render方法被調(diào)用時(shí),組件會(huì)發(fā)生更新過程,這個(gè)時(shí)候,組件props的值可能發(fā)生改變,也可能沒有改變,因?yàn)楦附M件可以使用相同的對(duì)象或值為組件的props賦值。但是,無論props是否改變,父組件render方法每一次調(diào)用,都會(huì)導(dǎo)致組件更新。State引起的組件更新,是通過調(diào)用this.setState修改組件state來觸發(fā)的。組件更新階段,依次調(diào)用的生命周期方法有:
(1)componentWillReceiveProps
(2)shouldComponentUpdate
(3)componentWillUpdate
(4)render
(5)componentDidUpdate
1.componentWillReceiveProps(nextProps)
這個(gè)方法只在props引起的組件更新過程中,才會(huì)被調(diào)用。State引起的組件更新并不會(huì)觸發(fā)該方法的執(zhí)行。方法的參數(shù)nextProps是父組件傳遞給當(dāng)前組件的新的props。但如上文所述,父組件render方法的調(diào)用并不能保證傳遞給子組件的props發(fā)生變化,也就是說nextProps的值可能和子組件當(dāng)前props的值相等,因此往往需要比較nextProps和this.props來決定是否執(zhí)行props發(fā)生變化后的邏輯,比如根據(jù)新的props調(diào)用this.setState觸發(fā)組件的重新渲染。
注意
(1)在componentWillReceiveProps中調(diào)用setState,只有在組件render及其之后的方法中,this.state指向的才是更新后的state。在render之前的方法shouldComponentUpdate、componentWillUpdate中,this.state依然指向的是更新前的state。
(2)通過調(diào)用setState更新組件狀態(tài)并不會(huì)觸發(fā)componentWillReceiveProps的調(diào)用,否則可能會(huì)進(jìn)入一個(gè)死循環(huán),componentWillReceiveProps→this.setState→componentWillReceiveProps→this.setState……
2.shouldComponentUpdate(nextProps, nextState)
這個(gè)方法決定組件是否繼續(xù)執(zhí)行更新過程。當(dāng)方法返回true時(shí)(true也是這個(gè)方法的默認(rèn)返回值),組件會(huì)繼續(xù)更新過程;當(dāng)方法返回false時(shí),組件的更新過程停止,后續(xù)的componentWillUpdate、render、componentDidUpdate也不會(huì)再被調(diào)用。一般通過比較nextProps、nextState和組件當(dāng)前的props、state決定這個(gè)方法的返回結(jié)果。這個(gè)方法可以用來減少組件不必要的渲染,從而優(yōu)化組件的性能。
3.componentWillUpdate(nextProps, nextState)
這個(gè)方法在組件render調(diào)用前執(zhí)行,可以作為組件更新發(fā)生前執(zhí)行某些工作的地方,一般也很少用到。
注意
shouldComponentUpdate和componentWillUpdate中都不能調(diào)用setState,否則會(huì)引起循環(huán)調(diào)用問題,render永遠(yuǎn)無法被調(diào)用,組件也無法正常渲染。
4.componentDidUpdate(prevProps, prevState)
組件更新后被調(diào)用,可以作為操作更新后的DOM的地方。這個(gè)方法的兩個(gè)參數(shù)prevProps、prevState代表組件更新前的props和state。
2.3.3 卸載階段
組件從DOM中被卸載的過程,這個(gè)過程中只有一個(gè)生命周期方法:

這個(gè)方法在組件被卸載前調(diào)用,可以在這里執(zhí)行一些清理工作,比如清除組件中使用的定時(shí)器,清除componentDidMount中手動(dòng)創(chuàng)建的DOM元素等,以避免引起內(nèi)存泄漏。
最后還需要提醒大家,只有類組件才具有生命周期方法,函數(shù)組件是沒有生命周期方法的,因此永遠(yuǎn)不要在函數(shù)組件中使用生命周期方法。
- 手機(jī)結(jié)構(gòu)設(shè)計(jì)完全自學(xué)與速查手冊(cè)
- 完美講堂 Unity3D手機(jī)游戲開發(fā)實(shí)戰(zhàn)教程
- 中國自動(dòng)化技術(shù)發(fā)展報(bào)告
- 現(xiàn)代交換原理
- 信號(hào)與系統(tǒng)習(xí)題指導(dǎo)
- 開關(guān)電源維修從入門到精通(第3版)
- 教你檢修液晶彩色電視機(jī)
- 5G 移動(dòng)性管理技術(shù)
- 數(shù)字視聽產(chǎn)品原理與維修
- 5G來了:5G如何改變生活、社會(huì)和產(chǎn)業(yè)
- 輕松解讀電子節(jié)能電器電路
- 物聯(lián)網(wǎng)在中國的探索與實(shí)踐
- 電子元器件檢測與應(yīng)用
- LED制造技術(shù)與應(yīng)用
- 任務(wù)驅(qū)動(dòng)學(xué)電視機(jī)維修技術(shù)