此文是我的出版書籍《React Native 精解與實戰》連載分享,此書由機械工業出版社出版,書中詳解了 React Native 架構底層原理、React Native 組件布局、組件與 API 的介紹與代碼實戰,以及 React Native 與 iOS、Android 平台的混合開發底層原理講解與代碼實戰示範,精選了大量執行個體代碼,方便讀者快速學習。
書籍還配套了視頻教程「80 節實戰課精通 React Native 開發」,此視頻課程建議配合書籍學習,書籍中原理性的東西講解的比較清晰,而視頻教程對於組件、API 等部分的代碼實戰開發講解比較直觀。
書籍相關所有資料請訪問:http://rn.parryqiu.com
3.5 生命週期概念
任何生命體都會經曆從出生到消亡的過程,而 React Native 架構中的組件同樣具有這樣的屬性。
在組件生命週期的每個階段,React Native 提供了多個生命週期函數,供開發人員作為切入組件生命週期的鉤子(hook),這樣在對應的時間點程式就可以做對應的邏輯處理,從而實現相應的功能。
在 React Native 程式啟動時,內部的虛擬 DOM 開始建立,生命週期就是建立在此虛擬 DOM 的整個生命週期之中,從虛擬 DOM 的初始化到虛擬 DOM 的卸載,React Native 為組件的不同狀態建立了不同的生命週期。
3.6 React Native 中的生命週期
在圖 3-4 中,可以看到在 React Native 虛擬 DOM 的幾個大的階段中,都有對應的生命週期函數存在。
圖 3-4 React Native 生命週期
1. 初始化階段
此階段進行組件的預設 props 和 state 的設定,可通過如下代碼賦值。
1. static defaultProps = { 2. autoPlay: false, 3. maxLoop: 10, 4. };
2. 載入階段
此階段為組件開始執行個體化的階段,比如當該組件開始被其他組件調用的時候。主要包含以下三個生命週期函數。
componentWillMount:組件將要開始載入,需要在組件開始載入前添加一些商務邏輯,那麼就可以添加在此函數中。
render:組件開始根據 props 和 state 產生頁面的 DOM,並在最後返回此 DOM。在此函數中不可以修改 props 和 state 的值,只可以讀取,並且返回的 DOM 只能有一個頂層元素,比如說只能由一個 div 包裹所有的元素進行返回。
componentDidMount:組件已載入完畢,在 render 函數之後立即執行此函數。一般可以在這裡進行網路請求,因為組件 UI 渲染好之後再進行網路請求,一般不會造成 UI 的錯亂問題。在此生命週期函數中修改設定了 state 的值後,UI 會立即進行重新渲染,所以是一個通過載入網路資料更新 UI 的好時機。
3. 更新階段此階段一般因為使用者操作或者父組件有更新時,當組件因為 props 或 state 的變更導致組件重新渲染時,會經曆此階段。而在更新渲染的幾個重要時機,React Native 提供了如下的生命週期函數供開發人員執行對應的邏輯操作。
componentWillReceiveProps:當接收到新的 props 值更新時,會執行到此生命週期函數,此時可以將接收到的 props 值賦值給 state。
shouldComponentUpdate:在此生命週期中,可以通過邏輯判斷新的 props 和 state 的變更需不需要引起組件的 UI 更新,預設是都會引起更新的,但是 React Native 提供了此生命週期供開發人員自主決定是否需要更新。如果讓此函數返回 True,那麼組件將進行更新,如果返回 False,那麼組件就不更新。此生命週期在最佳化 App 效能時非常重要,因為可以通過此生命週期函數攔截掉很多不必要的組件 UI 更新。
componentWillUpdate:如果上面的生命週期函數 shouldComponentUpdate 返回了 True,那麼此生命週期函數將繼續執行,表示組件即將進行更新操作。在更新操作前,還有時機進行相關的邏輯處理。但是從邏輯上你也應該明白,這裡不可以再修改 state 的值,而只可以做一些進行更新前的其他準備工作。
componentDidUpdate:組件更新完畢之後執行的生命週期函數。此函數有兩個參數 prevProps 和 prevState,分別為更新前的 props 與 state。這裡可以進行一些新舊值的比較,如果發現值有變化可以進行一些網路請求、載入資料等操作。
4. 卸載階段
componentWillUnmount:此生命週期函數在組件被卸載和登出前執行,這裡可以進行一些所謂的掃尾工作,如關閉掉之前的網路請求、一些不必要儲存的清空、迴圈執行的定時器的清除等等。
至此,React Native 一個組件的完整生命週期執行完畢,你可以通過下面的代碼體會 React Native 每個生命週期的執行過程。實際開發時只需要根據實際的項目需求在對應的生命週期函數中添加上自己的商務邏輯即可。
1. /** 2. * 章節: 03-06 3. * React Native 中的生命週期 4. * FilePath: /03-06/lifecycle.js 5. * @Parry 6. */ 7. 8. import React, { Component } from 'react'; 9. import { AppRegistry,View,Text } from 'react-native'; 10. 11. export default class LifeCycle extends Component { 12. 13. constructor(props) { 14. super(props); 15. this.state = { 16. name: "React" 17. } 18. } 19. 20. //組件即將載入 21. componentWillMount() { 22. console.log("componentWillMount"); 23. } 24. 25. //開始組件渲染 26. render() { 27. console.log("render"); 28. return ( 29. <View> 30. <Text> 31. {this.state.name} 32. </Text> 33. </View> 34. ); 35. } 36. 37. //組件載入完畢後 38. componentDidMount() { 39. console.log("componentDidMount"); 40. } 41. 42. //組件接收到新的 props 43. componentWillReceiveProps(nextProps) { 44. console.log("componentWillReceiveProps"); 45. } 46. 47. //邏輯控制是否需要更新群組件 48. shouldComponentUpdate(nextProps, nextState) { 49. console.log("shouldComponentUpdate"); 50. } 51. 52. //組件即將更新重新渲染 53. componentWillUpdate(nextProps, nextState) { 54. console.log("componentWillUpdate"); 55. } 56. 57. //組件重新渲染後 58. componentDidUpdate(prevProps, prevState) { 59. console.log("componentDidUpdate"); 60. } 61. 62. //組件卸載登出前 63. componentWillUnmount() { 64. console.log("componentWillUnmount"); 65. } 66. } 67. 68. AppRegistry.registerComponent('LifeCycle', () => Main);
3.7 本章小結
本章如同修鍊武功中必備的內功一樣,看起來和使用 React Native 架構的關係不大,而且底層原理的部分理解起來還有點晦澀難懂。不過,如果你想成為一個精通 React Native 架構的開發人員,而不僅僅是一個使用者的話,這部分的內容是非常重要的,而且在後期你遇到此架構的難題時,你可以快速地根據這部分底層原理性的知識快速定位到問題所在。其他軟體開發語言的學習原則也是如此,希望能對你有所有啟發。