官术网_书友最值得收藏!

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ù)組件中使用生命周期方法。

主站蜘蛛池模板: 炉霍县| 辽阳市| 石台县| 股票| 丹棱县| 松溪县| 资阳市| 手游| 合山市| 和田县| 三台县| 运城市| 茌平县| 扎兰屯市| 卓资县| 如皋市| 平和县| 商河县| 前郭尔| 攀枝花市| 南充市| 宝清县| 冀州市| 乌兰县| 绥江县| 邻水| 铅山县| 施秉县| 辽阳市| 盱眙县| 瑞金市| 灵石县| 龙岩市| 丽水市| 晋城| 三台县| 蓬安县| 社会| 麻城市| 宁乡县| 边坝县|