一. 概念
1. 什么是組件的生命周期竿音?
組件從被創(chuàng)建到被銷毀的過(guò)程稱為組件的生命周期拒迅。React為組件在不同生命周期提供了不同的生命周期方法施符,方便我們更好地控制組件的行為甲馋。
2. 組件的生命周期主要包括哪幾個(gè)階段?
通常嗜湃,組件的生命周期可以被分為三個(gè)階段: '掛載階段'奈应、'更新階段'、`卸載階段`购披。
-
注意:
只有類組件才具有生命周期方法杖挣,函數(shù)組件是沒(méi)有生命周期方法的。因此永遠(yuǎn)不要在函數(shù)組件中使用生命周期方法刚陡。
二. 掛載階段
在這個(gè)階段組件被創(chuàng)建惩妇,執(zhí)行初始化株汉,并被掛載到DOM中,完成組件的第一次渲染屿附。
組件被創(chuàng)建 -> 執(zhí)行初始化 -> 被掛載到DOM -> 組件第一次渲染
在組件的掛載階段郎逃,依次調(diào)用的生命周期方法:
1. constructor()
2. componentWillMount()
3. render()
4. componentDidMount()
2.1 constructor
constructor
是ES6 class
的構(gòu)造方法哥童,組件被創(chuàng)建時(shí)會(huì)首先調(diào)用組件的構(gòu)造方法挺份。這個(gè)構(gòu)造方法接收一個(gè)由父屬性傳入的props
參數(shù)(對(duì)象),如果父組件中沒(méi)有傳入屬性而組件自身定義了默認(rèn)屬性贮懈,那么這個(gè)props
指向的就是組件的默認(rèn)屬性匀泊。- 必須在這個(gè)方法中首先調(diào)用
super(props)
才能保證props
被傳入組件中。constructor()
通常用于初始化組件的state
朵你,以及綁定事件的處理方法等工作各聘。
2.2 componentWillMount
- 這個(gè)方法在組件被掛載到DOM前調(diào)用,而且只會(huì)被調(diào)用一次抡医。在實(shí)際項(xiàng)目中很少會(huì)用到該方法躲因,因?yàn)樵摲椒ㄖ袌?zhí)行的工作其實(shí)都可以提前放到
constructor
中。- 在這個(gè)方法中調(diào)用
this.setState()
并不會(huì)引起組件的重新渲染忌傻。
2.3 render
(輸入) props && state
=> render()
=> React元素
(輸出)
render()
是定義組件是唯一必要的方法大脉,組件的其他生命周期方法都可以省略。- 在
render()
方法中水孩,根據(jù)組件的props
和state
返回一個(gè)React元素镰矿,用于描述組件的UI,通常React元素使用JSX語(yǔ)法定義俘种。(JSX實(shí)際上調(diào)用React.createElement()
方法)render
并不負(fù)責(zé)組件的實(shí)際渲染工作秤标,它只是一個(gè)UI的描述,真正渲染出頁(yè)面DOM的工作由React自身負(fù)責(zé)宙刘。render
是一個(gè)純函數(shù)苍姜,在這個(gè)方法中不能執(zhí)行任何有副作用的操作,不能去改變組件的狀態(tài)悬包。因此怖现,在render()
中不能調(diào)用this.setState()
。
2.4 componentDidMount
componentDidMount()
在組件被掛載到DOM之后調(diào)用玉罐,而且該方法只會(huì)被調(diào)用一次屈嗤。這個(gè)時(shí)候已經(jīng)可以獲取到DOM結(jié)構(gòu),因此依賴DOM節(jié)點(diǎn)的操作可以放到該方法中吊输。此外饶号,這個(gè)方法通常還會(huì)用于向服務(wù)器端請(qǐng)求數(shù)據(jù)。- 在這個(gè)方法中可以調(diào)用
this.setState()
季蚂,調(diào)用this.setState()
會(huì)引起組件的重新渲染茫船。
- 組件掛載階段幾個(gè)生命周期方法的比較
能否調(diào)用this.setState()
|
引起組件重新渲染 | 僅調(diào)用一次 | 必要性 | 主要作用 | |
---|---|---|---|---|---|
constructor | 初始化State
|
?? | ?? | ?? | 初始化組件的state 琅束、綁定事件的處理方法 |
componentWillMount | ?? | ?? | ?? | ?? | 很少用 |
render | ?? | ?? | ?? | 描述組件UI | |
componentDidMount | ?? | ?? | ?? | ?? | 依賴DOM節(jié)點(diǎn)的操作、請(qǐng)求服務(wù)器數(shù)據(jù) |
三. 更新階段
組件被掛載到DOM后算谈,
props
或state
都可以引起組件的更新涩禀。props
引起的組件更新,本質(zhì)上是由渲染該組件的父組件引起的然眼,無(wú)論props
是否改變艾船,當(dāng)父組件的render()
方法每一次被調(diào)用時(shí),都會(huì)導(dǎo)致組件的更新高每。State
引起的組件更新屿岂,則是通過(guò)調(diào)用this.setState()
修改組件的state
來(lái)觸發(fā)的。
父組件.render(props) / this.setState() -> 組件更新
在組件更新階段鲸匿,依次調(diào)用的生命周期方法:
1. componentWillReceiveProps()
2. shouldComponentUpdate()
3. componentWillUpdate()
4. render()
5. componentDidUpdate()
3.1 componentWillReceiveProps(nextProps)
componentWillReceiveProps()
只會(huì)在由props引起的組件更新過(guò)程中被調(diào)用爷怀,由state引起的組件更新并不會(huì)觸發(fā)該方法的執(zhí)行。componentWillReceiveProps
方法的參數(shù)nextProps
是父組件傳遞給當(dāng)前組件的新的props
带欢。往往需要比較nextProps
和this.props
來(lái)決定是否執(zhí)行props
發(fā)生變化后的邏輯运授,比如根據(jù)新的props
調(diào)用this.setState
觸發(fā)組件的重新渲染。- 在
componentWillReceiveProps()
中調(diào)用setState
乔煞,只有在組件render
及其之后的方法中吁朦,this.setState
指向的才是更新后的state
,在組件render
之前的方法中(shouldComponentUpdate / componentWillUpdate
)瘤缩,this.setState
依然指向的是更新前的state
喇完。- 可以調(diào)用
this.setState
,但是通過(guò)調(diào)用this.setState
更新組件狀態(tài)并不會(huì)觸發(fā)componentWillReceiveProps
的調(diào)用剥啤,否則會(huì)進(jìn)入一個(gè)死循環(huán)锦溪。
3.2 shouldComponentUpdate(nextProps,nextState)
shouldComponentUpdate
決定組件是否繼續(xù)執(zhí)行更新過(guò)程府怯。當(dāng)該方法返回true
(默認(rèn)值)時(shí)刻诊,組件繼續(xù)更新,當(dāng)返回false
時(shí)牺丙,組件的更新過(guò)程停止则涯,后續(xù)的componentWillUpdate
、render
冲簿、componentDidUpdate
也不會(huì)再被調(diào)用粟判。shouldComponentUpdate
可以用來(lái)減少組件不必要的渲染,從而優(yōu)化組件的性能峦剔。- 不能調(diào)用
this.setState
档礁,否則會(huì)引起循環(huán)調(diào)用問(wèn)題。導(dǎo)致render
永遠(yuǎn)無(wú)法被調(diào)用吝沫,組件無(wú)法正常渲染呻澜。
3.3 componentWillUpdate(nextProps递礼,nextState)
- 該方法在組件
render
之前執(zhí)行,一般也很少用到羹幸。- 不能調(diào)用
this.setState
脊髓,否則會(huì)引起循環(huán)調(diào)用問(wèn)題所刀。導(dǎo)致render
永遠(yuǎn)無(wú)法被調(diào)用押赊,組件無(wú)法正常渲染。
3.4 render
3.5 componentDidUpdate(prevProps涨薪,prevState)
componentDidUpdate
在組件更新之后被調(diào)用窘疮,可以作為操作更新后的DOM的地方袋哼。該方法的兩個(gè)參數(shù)prevProps
冀墨、prevState
代表組件更新前的props
和state
闸衫。
- 組件更新階段幾個(gè)生命周期方法的比較
能否調(diào)用this.setState()
|
引起組件重新渲染 | 引起組件更新 | 參數(shù) | 必要性 | 主要作用 | |
---|---|---|---|---|---|---|
componentWillReceiveProps | ?? | ?? | props |
nextProps |
?? | 根據(jù)props 的變化來(lái)決定是否執(zhí)行之后的邏輯 |
shouldComponentUpdate | ?? | props && state |
nextProps nextState
|
?? | 可用來(lái)減少組件不必要的渲染,從而優(yōu)化組件的性能 | |
componentWillUpdate | ?? | props && state |
nextProps nextState
|
?? | 很少用 | |
render | ?? | props && state |
?? | 描述組件UI | ||
componentDidUpdate | ?? | ?? | props && state |
prevProps prevState
|
?? | 操作更新后的DOM |
四. 卸載階段
組件的卸載階段是組件從DOM中被卸載的過(guò)程诽嘉。
在組件卸載階段蔚出,只有
一個(gè)
生命周期方法:
1. componentWillUnmount()
4.1 componentWillUnmount
componentWillUnmount
在組件被卸載前調(diào)用,可以在這里執(zhí)行一些清理工作虫腋,比如清除組件中使用的定時(shí)器骄酗,清除componentDidMount
中手動(dòng)創(chuàng)建的DOM元素等,以避免引起內(nèi)存泄露悦冀。