React-Native之生命週期
概述
就像 Android 開發中的 View 一樣,React Native(RN) 中的元件也有生命週期(Lifecycle)。所謂生命週期,就是一個物件從開始生成到最後消亡所經歷的狀態,理解生命週期,是合理開發的關鍵。RN 元件的生命週期整理如下圖:
如圖,可以把元件生命週期大致分為三個階段:
- 第一階段:是元件第一次繪製階段,如圖中的上面虛線框內,在這裡完成了元件的載入和初始化;
- 第二階段:是元件在執行和互動階段,如圖中左下角虛線框,這個階段元件可以處理使用者互動,或者接收事件更新介面;
- 第三階段:是元件解除安裝消亡的階段,如圖中右下角的虛線框中,這裡做一些元件的清理工作。
生命週期回撥函式
下面來詳細介紹生命週期中的各回調函式。
getDefaultProps
在元件建立之前,會先呼叫getDefaultProps(),這是全域性呼叫一次,嚴格地來說,這不是元件的生命週期的一部分。在元件被建立並載入候,首先呼叫getInitialState(),來初始化元件的狀態。
componentWillMount
然後,準備載入元件,會呼叫componentWillMount(),其原型如下:
void componentWillMount()
這個函式呼叫時機是在元件建立,並初始化了狀態之後,在第一次繪製render()之前。可以在這裡做一些業務初始化操作,也可以設定元件狀態。這個函式在整個生命週期中只被呼叫一次。
componentDidMount
在元件第一次繪製之後,會呼叫componentDidMount(),通知元件已經載入完成。函式原型如下:
void componentDidMount()
這個函式呼叫的時候,其虛擬 DOM 已經構建完成,你可以在這個函式開始獲取其中的元素或者子元件了。需要注意的是,RN 框架是先呼叫子元件的componentDidMount(),然後呼叫父元件的函式。從這個函式開始,就可以和 JS 其他框架互動了,例如設定計時setTimeout或者setInterval,或者發起網路請求。這個函式也是隻被呼叫一次。這個函式之後,就進入了穩定執行狀態,等待事件觸發。
componentWillReceiveProps
如果元件收到新的屬性(props),就會呼叫componentWillReceiveProps(),其原型如下:
void componentWillReceiveProps( object nextProps )
輸入引數nextProps是即將被設定的屬性,舊的屬性還是可以通過this.props來獲取。在這個回撥函式裡面,你可以根據屬性的變化,通過呼叫this.setState()來更新你的元件狀態,這裡呼叫更新狀態是安全的,並不會觸發額外的render()呼叫。如下:
componentWillReceiveProps: function(nextProps) { this.setState({ likesIncreasing: nextProps.likeCount > this.props.likeCount }); }
shouldComponentUpdate
當元件接收到新的屬性和狀態改變的話,都會觸發呼叫shouldComponentUpdate(...),函式原型如下:
boolean shouldComponentUpdate( object nextProps, object nextState )
輸入引數nextProps和上面的componentWillReceiveProps函式一樣,nextState表示元件即將更新的狀態值。這個函式的返回值決定是否需要更新元件,如果true表示需要更新,繼續走後面的更新流程。否者,則不更新,直接進入等待狀態。
預設情況下,這個函式永遠返回true用來保證資料變化的時候 UI 能夠同步更新。在大型專案中,你可以自己過載這個函式,通過檢查變化前後屬性和狀態,來決定 UI 是否需要更新,能有效提高應用效能。
componentWillUpdate
如果元件狀態或者屬性改變,並且上面的shouldComponentUpdate(...)返回為true,就會開始準更新元件,並呼叫componentWillUpdate(),其函式原型如下:
void componentWillUpdate( object nextProps, object nextState )
輸入引數與shouldComponentUpdate一樣,在這個回撥中,可以做一些在更新介面之前要做的事情。需要特別注意的是,在這個函式裡面,你就不能使用this.setState來修改狀態。這個函式呼叫之後,就會把nextProps和nextState分別設定到this.props和this.state中。緊接著這個函式,就會呼叫render()來更新介面了。
componentDidUpdate
呼叫了render()更新完成介面之後,會呼叫componentDidUpdate()來得到通知,其函式原型如下:
void componentDidUpdate( object prevProps, object prevState )
因為到這裡已經完成了屬性和狀態的更新了,此函式的輸入引數變成了prevProps和prevState。
componentWillUnmount
當元件要被從介面上移除的時候,就會呼叫componentWillUnmount(),其函式原型如下:
void componentWillUnmount()
在這個函式中,可以做一些元件相關的清理工作,例如取消計時器、網路請求等。
總結
到這裡,RN 的元件的完整的生命都介紹完了,在回頭來看一下前面的圖,就比較清晰了,把生命週期的回撥函式總結成如下表格:
生命週期 | 呼叫次數 | 能否使用 setSate() |
---|---|---|
getDefaultProps | 1(全域性呼叫一次) | 否 |
getInitialState | 1 | 否 |
componentWillMount | 1 | 是 |
render | >=1 | 否 |
componentDidMount | 1 | 是 |
componentWillReceiveProps | >=0 | 是 |
shouldComponentUpdate | >=0 | 否 |
componentWillUpdate | >=0 | 否 |
componentDidUpdate | >=0 | 否 |
componentWillUnmount | 1 | 否 |
擴充套件閱讀
Moles框架,攜程基於React Native的跨平臺開發通往全棧工程師的捷徑 —— react
React 入門例項教程
【REACT NATIVE 系列教程之六】重寫shouldComponentUpdate指定元件是否進行重繪
React Native 的最佳輪播類元件:react-native-swiper