React-Native生命周期詳解

Hello大家好。大家可能會(huì)想問為什么最近公眾號(hào)不更新文章了,在這里說明一下。由于小編們近期工作和業(yè)務(wù)繁忙(我就不說是什么業(yè)務(wù)了,哈哈哈哈),需要靜養(yǎng),最近都沒來得及更新文章,希望大家理解見諒哈。這一期先由我來為大家奉上一篇。

上一期為大家講解了一個(gè)ListView的實(shí)戰(zhàn)項(xiàng)目,包括怎么網(wǎng)絡(luò)請(qǐng)求,怎么解析數(shù)據(jù),怎么布局等等,如果沒看過的可以去看鏈接。當(dāng)然沒看過也不影響這一期的學(xué)習(xí)。這一期主要帶大家了解RN組件的生命周期。好了,廢話不多說我們步入正題。

一.React-Native生命周期


說到生命周期,大家大概也能想到就是創(chuàng)建、銷毀、狀態(tài)改變。RN的組件就是一個(gè)狀態(tài)機(jī)。它接收兩個(gè)輸入?yún)?shù):props和state,返回一個(gè)Virtual DOM。和Native一樣,RN也為我們提供相應(yīng)的鉤子函數(shù)。RN的狀態(tài)變化取決于props和state。我們先來看一張經(jīng)典圖。

這張圖涵蓋了一個(gè)組件從創(chuàng)建、運(yùn)行到銷毀的整個(gè)過程。大家可以看到,初始化的時(shí)候會(huì)調(diào)用5個(gè)函數(shù)(按先后順序)。這5個(gè)函數(shù)在整個(gè)組件被創(chuàng)建到銷毀的過程中只調(diào)用一次。初始化完畢后,當(dāng)組件的props或者state改變都會(huì)觸發(fā)不同的鉤子函數(shù),繼而引發(fā)組件的重新渲染。現(xiàn)在我們把這過程拆開一點(diǎn)一點(diǎn)來分析。

初始化

我們先來看初始化,在初始化的過程中,會(huì)按順序調(diào)用下面5個(gè)函數(shù)。

getDefaultProps:組件實(shí)例創(chuàng)建前調(diào)用,多個(gè)實(shí)例間共享引用。注意:如果父組件傳遞過來的Props和你在該函數(shù)中定義的Props的key一樣,將會(huì)被覆蓋。

getInitalState:組件示例創(chuàng)建的時(shí)候調(diào)用的第一個(gè)函數(shù)。主要用于初始化state。注意:為了在使用中不出現(xiàn)空值,建議初始化state的時(shí)候盡可能給每一個(gè)可能用到的值都賦一個(gè)初始值。

componentWillMount:在render前,getInitalState之后調(diào)用。僅調(diào)用一次,可以用于改變state操作。

render:組件渲染函數(shù),會(huì)返回一個(gè)Virtual DOM,只允許返回一個(gè)最外層容器組件。render函數(shù)盡量保持純凈,只渲染組件,不修改狀態(tài),不執(zhí)行副操作(比如計(jì)時(shí)器)。

componentDidMount:在render渲染之后,React會(huì)根據(jù)Virtual DOM來生成真實(shí)DOM,生成完畢后會(huì)調(diào)用該函數(shù)。在瀏覽器端(React),我們可以通過this.getDOMNode()來拿到相應(yīng)的DOM節(jié)點(diǎn)。然而我們?cè)赗N中并用不到,在RN中主要在該函數(shù)中執(zhí)行網(wǎng)絡(luò)請(qǐng)求,定時(shí)器開啟等相關(guān)操作

下面我們來演示getDefaultProps初始化Props以及父組件覆蓋問題(AppConnect和Provider是和redux相關(guān)的代碼,大家請(qǐng)?zhí)^這一行):

比如我們?cè)谶@里定義了SimpleApp的默認(rèn)Props為一個(gè)key為name,value為wsd的字典(ES6以后廢除了getDefaultProps而使用上述方式),然后我們?cè)谒母附M件App中傳入一個(gè)同樣key為name的Props,然后我們?cè)赟impleApp中使用this.props.name把props打印出來,如下:

可以看到,原先的wsd被后面?zhèn)魅氲膋ingStart覆蓋了。

然后我們來看初始化State的演示(ES6里使用constructor):

我們初始化一個(gè)state為key為sex,value為boy的state對(duì)象,然后我們?cè)赾omponentWillMount函數(shù)中改變已經(jīng)初始化的sex和沒有聲明的age,最后在render中打?。?/p>

可以看到我們?cè)趓ender中打印出了state中兩個(gè)屬性的值。在這里我們需要注意的是,如果在componentWillMount中直接修改state的值不會(huì)引發(fā)render的再次渲染。而如果把修改state的操作放到在render執(zhí)行完之后的componentDidMount中,是會(huì)引發(fā)render的再次渲染的。

運(yùn)行中

初始化完成之后,組件將會(huì)進(jìn)入到運(yùn)行中狀態(tài),運(yùn)行中狀態(tài)我們將會(huì)遇到如下幾個(gè)函數(shù):

componentWillReceiveProps(nextProps):props改變(父容器來更改或是redux),將會(huì)調(diào)用該函數(shù)。新的props將會(huì)作為參數(shù)傳遞進(jìn)來,老的props可以根據(jù)this.props來獲取。我們可以在該函數(shù)中對(duì)state作一些處理。注意:在該函數(shù)中更新state不會(huì)引起二次渲染。

boolean shouldComponentUpdate(object nextProps, object nextState):該函數(shù)傳遞過來兩個(gè)參數(shù),新的state和新的props。state和props的改變都會(huì)調(diào)到該函數(shù)。該函數(shù)主要對(duì)傳遞過來的nextProps和nextState作判斷。如果返回true則重新渲染,如果返回false則不重新渲染。在某些特定條件下,我們可以根據(jù)傳遞過來的props和state來選擇更新或者不更新,從而提高效率。

componentWillUpdate(object nextProps, object nextState):與componentWillMount方法類似,組件上會(huì)接收到新的props或者state渲染之前,調(diào)用該方法。但是不可以在該方法中更新state和props。

render:跟初始化的時(shí)候功能一樣。

componentDidUpdate(object prevProps,object prevState):和初始化時(shí)期的componentDidMount類似,在render之后,真實(shí)DOM生成之后調(diào)用該函數(shù)。傳遞過來的是當(dāng)前的props和state。在該函數(shù)中同樣可以使用this.getDOMNode()來拿到相應(yīng)的DOM節(jié)點(diǎn)。如果你需要在運(yùn)行中執(zhí)行某些副操作,請(qǐng)?jiān)谠摵瘮?shù)中完成。

我們來演示componentWillReceiveProps的調(diào)用時(shí)機(jī),對(duì)于頂層組件,我們添加一個(gè)文本及一個(gè)點(diǎn)擊事件:

按鈕點(diǎn)擊以后,我們將自身state的name屬性改變,并傳遞給SimpleApp(這里的AppConnect就是SimpleApp),結(jié)果如下:

我們可以看到,第一次render,打印的是defaultProps傳過來的props。當(dāng)按鈕點(diǎn)擊,頂層組件state改變,引發(fā)頂層組件重新渲染,父組件傳遞的name發(fā)生改變,componentWillReceiveProps被調(diào)用,繼而引發(fā)二次渲染。在第二次render的時(shí)候,打印出來的就是新傳遞過來的props。

銷毀

銷毀階段只有一個(gè)函數(shù),很簡單

componentWillUnmount:組件DOM中移除的時(shí)候調(diào)用。在這里進(jìn)行一些相關(guān)的銷毀操作,比如定時(shí)器,監(jiān)聽等等。

為了加深記憶,我們把初始化和運(yùn)行中所有的鉤子函數(shù)寫出來,讓大家看看最終的運(yùn)行結(jié)果。

我們首先初始化組件,不執(zhí)行任何操作,打印結(jié)果如圖所示:

當(dāng)我們點(diǎn)擊按鈕,改變組件的props之后,打印結(jié)果如下:

我們給自身組件添加了一個(gè)點(diǎn)擊事件,點(diǎn)擊之后改變自身的state,如下:

點(diǎn)擊之后,再來看調(diào)用結(jié)果:

這也印證了我們的結(jié)論


二.props和state


上面講完了生命周期,我們對(duì)props和state的不同點(diǎn)以及相同點(diǎn)作一個(gè)總結(jié),加深大家理解。

相同點(diǎn)

1.不管是props還是state的改變,都會(huì)引發(fā)render的重新渲染。

2.都能由自身組件的相應(yīng)初始化函數(shù)設(shè)定初始值。

不同點(diǎn)

1.初始值來源:state的初始值來自于自身的getInitalState(constructor)函數(shù);props來自于父組件或者自身getDefaultProps(若key相同前者可覆蓋后者)。

2.修改方式:state只能在自身組件中setState,不能由父組件修改;props只能由父組件修改,不能在自身組件修改。

3.對(duì)子組件:props是一個(gè)父組件傳遞給子組件的數(shù)據(jù)流,這個(gè)數(shù)據(jù)流可以一直傳遞到子孫組件;state代表的是一個(gè)組件內(nèi)部自身的狀態(tài),只能在自身組件中存在。

以上總結(jié)盜用本站另一位小編的圖來解釋O(∩_∩)O~:

本章結(jié)束。打廣告打廣告了,喜歡全棧開發(fā)的猿友們,請(qǐng)不要忘記動(dòng)手掃一掃下面的二維碼關(guān)注我們喲O(∩_∩)O~。我們會(huì)繼續(xù)不定期推出有關(guān)于全棧的相關(guān)文章,敬請(qǐng)期待。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容