
一、概述
開發(fā)RN,必不可少的就是它的基礎(chǔ)框架react-native。對于框架的學(xué)習(xí),官網(wǎng)上有很多很詳細(xì)的介紹,這里就不多講了,ReactNative英文官網(wǎng)和ReactNative中文官網(wǎng)。像props、state等重要屬性都有講解,只是講的比較簡單,不太好理解。如果感覺不好理解,推薦去React官網(wǎng)看看。因?yàn)镽N就是基于reactjs來編寫的,下沉的去學(xué)習(xí)reactjs是使自己的操作更規(guī)范的一個不錯方法。
特別推薦一篇React 哲學(xué),它主要講從UI設(shè)計(jì)到狀態(tài)處理,最后到數(shù)據(jù)流的一個過程。有一定基礎(chǔ)的RN開發(fā)一定要看看,特別重要。
看完之后,就被這句話圈粉了。。。
二、生命周期圖譜

如圖,可以把RN組件生命周期大致分為三個階段:
- 第一階段:是組件第一次繪制階段,如圖中的上面虛線框內(nèi),在這里完成了組件的加載和初始化;
- 第二階段:是組件在運(yùn)行和交互階段,如圖中左下角虛線框,這個階段組件可以處理用戶交互,或者接收事件更新界面;
- 第三階段:是組件卸載消亡的階段,如圖中右下角的虛線框中,這里做一些組件的清理工作。
三、生命周期函數(shù)
3.1getDefaultProps
在組件創(chuàng)建之前,會先調(diào)用getDefaultProps(),這是全局調(diào)用一次,嚴(yán)格地來說,這不是組件的生命周期的一部分。在組件被創(chuàng)建并加載后,首先調(diào)用getInitialState(),來初始化組件的狀態(tài)。
3.2getInitialState
該函數(shù)用于對組件一些狀態(tài)進(jìn)行初始化,不同于getDefaultProps,在以后的過程中,會再次調(diào)用,所以可以將控制控件狀態(tài)的一些變量放在這里初始化,比如控件上顯示的文字,可以通過this.state來獲取值,通過this.setState來修改state值。注意:一旦調(diào)用了this.setState方法,組件一定會調(diào)用render方法,對組件進(jìn)行再次渲染,不過,React框架會根據(jù)DOM的狀態(tài)自動判斷是否需要真正渲染。
3.3componentWillMount
準(zhǔn)備加載組件,會調(diào)用componentWillMount(),這個函數(shù)調(diào)用時機(jī)是在組件創(chuàng)建,并初始化了狀態(tài)之后,在第一次繪制render()之前??梢栽谶@里做一些業(yè)務(wù)初始化操作,也可以設(shè)置組件狀態(tài)。這個函數(shù)在整個生命周期中只被調(diào)用一次。
void componentWillMount()
3.4render
render函數(shù)會插入jsx生成的dom結(jié)構(gòu),react會生成一份虛擬dom樹,在每一次組件更新時,在此react會通過其diff算法比較更新前后的新舊DOM樹,比較以后,找到最小的有差異的DOM節(jié)點(diǎn),并重新渲染。
3.5componentDidMount
在組件第一次繪制之后,會調(diào)用componentDidMount(),通知組件已經(jīng)加載完成。這個函數(shù)調(diào)用的時候,其虛擬 DOM 已經(jīng)構(gòu)建完成,你可以在這個函數(shù)開始獲取其中的元素或者子組件了。需要注意的是,RN 框架是先調(diào)用子組件的componentDidMount(),然后調(diào)用父組件的函數(shù)。從這個函數(shù)開始,就可以和 JS 其他框架交互了,例如設(shè)置計(jì)時setTimeout或者setInterval,或者發(fā)起網(wǎng)絡(luò)請求。這個函數(shù)也是只被調(diào)用一次。這個函數(shù)之后,就進(jìn)入了穩(wěn)定運(yùn)行狀態(tài),等待事件觸發(fā)。
void componentDidMount()
3.6componentWillReceiveProps
如果組件收到新的屬性(props),就會調(diào)用componentWillReceiveProps(),輸入?yún)?shù)nextProps是即將被設(shè)置的屬性,舊的屬性還是可以通過this.props來獲取。在這個回調(diào)函數(shù)里面,你可以根據(jù)屬性的變化,通過調(diào)用this.setState()來更新你的組件狀態(tài),這里調(diào)用更新狀態(tài)是安全的,并不會觸發(fā)額外的render()調(diào)用。
void componentWillReceiveProps(object nextProps)
3.7shouldComponentUpdate
當(dāng)組件接收到新的屬性和狀態(tài)改變的話,都會觸發(fā)調(diào)用shouldComponentUpdate(...),輸入?yún)?shù)nextProps和上面的componentWillReceiveProps函數(shù)一樣,nextState表示組件即將更新的狀態(tài)值。這個函數(shù)的返回值決定是否需要更新組件,如果true表示需要更新,繼續(xù)走后面的更新流程。否者,則不更新,直接進(jìn)入等待狀態(tài)。默認(rèn)情況下,這個函數(shù)永遠(yuǎn)返回true用來保證數(shù)據(jù)變化的時候 UI 能夠同步更新。在大型項(xiàng)目中,你可以自己重載這個函數(shù),通過檢查變化前后屬性和狀態(tài),來決定 UI 是否需要更新,能有效提高應(yīng)用性能。
boolean shouldComponentUpdate(object nextProps, object nextState)
3.8componentWillUpdate
如果組件狀態(tài)或者屬性改變,并且上面的shouldComponentUpdate(...)返回為true,就會開始準(zhǔn)更新組件,并調(diào)用componentWillUpdate(),輸入?yún)?shù)與shouldComponentUpdate一樣,在這個回調(diào)中,可以做一些在更新界面之前要做的事情。需要特別注意的是,在這個函數(shù)里面,你就不能使用this.setState來修改狀態(tài)。這個函數(shù)調(diào)用之后,就會把nextProps和nextState分別設(shè)置到this.props和this.state中。緊接著這個函數(shù),就會調(diào)用render()來更新界面了。
void componentWillUpdate(object nextProps, object nextState)
3.9componentDidUpdate
調(diào)用了render()更新完成界面之后,會調(diào)用componentDidUpdate()來得到通知,因?yàn)榈竭@里已經(jīng)完成了屬性和狀態(tài)的更新了,此函數(shù)的輸入?yún)?shù)變成了prevProps和prevState。
void componentDidUpdate(object prevProps, object prevState)
3.10componentWillUnmount
當(dāng)組件要被從界面上移除的時候,就會調(diào)用componentWillUnmount(),在這個函數(shù)中,可以做一些組件相關(guān)的清理工作,例如取消計(jì)時器、網(wǎng)絡(luò)請求等。
void componentWillUnmount()
3.11constructor
構(gòu)造函數(shù)在生命周期圖譜中沒有體現(xiàn),但是它是組件構(gòu)造時候必須調(diào)用的函數(shù)。constructor參數(shù)接受兩個參數(shù)props,context,可以獲取到父組件傳下來的props,context,如果你想在constructor構(gòu)造函數(shù)內(nèi)部(注意是內(nèi)部哦,在組件其他地方是可以直接接收的)使用props或context,則需要傳入,并傳入super對象。當(dāng)然如果你只需要在構(gòu)造函數(shù)內(nèi)使用props或者context,那么只傳入一個參數(shù)即可,如果都不可以,就都不傳。注意:只要組件存在constructor,就必要要寫super,否則this指向會錯誤。
四、調(diào)用

歡迎大佬糾錯指導(dǎo),歡迎同行交流學(xué)習(xí)。
GitHub:https://github.com/Code4GL
簡書:http://www.itdecent.cn/u/7f5541a6b6d2
知乎:https://www.zhihu.com/people/code4gl/activities
公眾號:code_everything
QQ:771841496
郵箱:guanli1991@163.com

