概述
就像 Android 開發(fā)中的 View 一樣,React Native(RN) 中的組件也有生命周期(Lifecycle)。所謂生命周期辑甜,就是一個對象從開始生成到最后消亡所經(jīng)歷的狀態(tài),理解生命周期练俐,是合理開發(fā)的關鍵袖迎。RN 組件的生命周期整理如下圖:
如圖冕臭,可以把組件生命周期大致分為三個階段:
- 第一階段:是組件第一次繪制階段,如圖中的上面虛線框內燕锥,在這里完成了組件的加載和初始化辜贵;
- 第二階段:是組件在運行和交互階段,如圖中左下角虛線框归形,這個階段組件可以處理用戶交互托慨,或者接收事件更新界面;
- 第三階段:是組件卸載消亡的階段暇榴,如圖中右下角的虛線框中厚棵,這里做一些組件的清理工作。
生命周期回調函數(shù)
下面來詳細介紹生命周期中的各回調函數(shù)蔼紧。
getDefaultProps
在組件創(chuàng)建之前婆硬,會先調用 getDefaultProps()
,這是全局調用一次奸例,嚴格地來說彬犯,這不是組件的生命周期的一部分。在組件被創(chuàng)建并加載候查吊,首先調用 getInitialState()
谐区,來初始化組件的狀態(tài)。
componentWillMount
然后逻卖,準備加載組件宋列,會調用 * componentWillMount()*
,其原型如下:
void componentWillMount()
這個函數(shù)調用時機是在組件創(chuàng)建评也,并初始化了狀態(tài)之后炼杖,在第一次繪制 render()
之前〕鸩危可以在這里做一些業(yè)務初始化操作嘹叫,也可以設置組件狀態(tài)。這個函數(shù)在整個生命周期中只被調用一次诈乒。
componentDidMount
在組件第一次繪制之后罩扇,會調用 * componentDidMount() *
,通知組件已經(jīng)加載完成。函數(shù)原型如下:
void componentDidMount()
這個函數(shù)調用的時候喂饥,其虛擬 DOM 已經(jīng)構建完成消约,你可以在這個函數(shù)開始獲取其中的元素或者子組件了。需要注意的是员帮,RN 框架是先調用子組件的 * componentDidMount()*或粮,然后調用父組件的函數(shù)。從這個函數(shù)開始捞高,就可以和 JS 其他框架交互了氯材,例如設置計時 setTimeout 或者 setInterval,或者發(fā)起網(wǎng)絡請求硝岗。這個函數(shù)也是只被調用一次氢哮。這個函數(shù)之后,就進入了穩(wěn)定運行狀態(tài)型檀,等待事件觸發(fā)冗尤。
componentWillReceiveProps
如果組件收到新的屬性(props),就會調用 componentWillReceiveProps()
胀溺,其原型如下:
void componentWillReceiveProps( object nextProps)
輸入?yún)?shù) nextProps
是即將被設置的屬性裂七,舊的屬性還是可以通過 this.props
來獲取。在這個回調函數(shù)里面仓坞,你可以根據(jù)屬性的變化背零,通過調用 this.setState()
來更新你的組件狀態(tài),這里調用更新狀態(tài)是安全的扯躺,并不會觸發(fā)額外的 render()
調用捉兴。如下:
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
shouldComponentUpdate
當組件接收到新的屬性和狀態(tài)改變的話,都會觸發(fā)調用 shouldComponentUpdate(...)
录语,函數(shù)原型如下:
boolean shouldComponentUpdate( object nextProps, object nextState)
輸入?yún)?shù) nextProps和上面的 componentWillReceiveProps函數(shù)一樣倍啥,nextState表示組件即將更新的狀態(tài)值。這個函數(shù)的返回值決定是否需要更新組件澎埠,如果* true* 表示需要更新虽缕,繼續(xù)走后面的更新流程。否則蒲稳,則不更新氮趋,直接進入等待狀態(tài)。
默認情況下江耀,這個函數(shù)永遠返回 true
用來保證數(shù)據(jù)變化的時候 UI 能夠同步更新剩胁。在大型項目中,你可以自己重載這個函數(shù)祥国,通過檢查變化前后屬性和狀態(tài)昵观,來決定 UI 是否需要更新晾腔,能有效提高應用性能。
componentWillUpdate
如果組件狀態(tài)或者屬性改變啊犬,并且上面的 shouldComponentUpdate(...)返回為 true灼擂,就會開始準更新組件,并調用 componentWillUpdate()觉至,其函數(shù)原型如下:
void componentWillUpdate( object nextProps, object nextState)
輸入?yún)?shù)與 * shouldComponentUpdate*
一樣剔应,在這個回調中,可以做一些在更新界面之前要做的事情语御。需要特別注意的是峻贮,在這個函數(shù)里面,你就不能使用 this.setState 來修改狀態(tài)沃暗。這個函數(shù)調用之后月洛,就會把 nextProps 和 nextState 分別設置到 this.props 和 this.state 中何恶。緊接著這個函數(shù)孽锥,就會調用 render() 來更新界面了。
componentDidUpdate
調用了 render()
更新完成界面之后细层,會調用 componentDidUpdate()
來得到通知惜辑,其函數(shù)原型如下:
void componentDidUpdate( object prevProps, object prevState)
因為到這里已經(jīng)完成了屬性和狀態(tài)的更新了,此函數(shù)的輸入?yún)?shù)變成了 prevProps
和 prevState
疫赎。
componentWillUnmount
當組件要被從界面上移除的時候盛撑,就會調用 * componentWillUnmount()*
,其函數(shù)原型如下:
void componentWillUnmount()
在這個函數(shù)中捧搞,可以做一些組件相關的清理工作抵卫,例如取消計時器、網(wǎng)絡請求等胎撇。
總結
到這里介粘,RN 的組件的完整的生命都介紹完了,在回頭來看一下前面的圖晚树,就比較清晰了
生命周期 | 調用次數(shù) | 能否使用 setSate() |
---|---|---|
getDefaultProps | 1(全局調用一次) | 否 |
getInitialState | 1 | 否 |
componentWillMount | 1 | 是 |
render | >=1 | 否 |
componentDidMount | 1 | 是 |
componentWillReceiveProps | >=0 | 是 |
shouldComponentUpdate | >=0 | 否 |
componentWillUpdate | >=0 | 否 |
componentDidUpdate | >=0 | 否 |
componentWillUnmount | 1 | 否 |