09 React Native組件生命周期

(申明: 此系列教程,轉載旋之華微信公眾號,如有侵權 . 通知刪除~)

(大家可以添加他的微信公眾號了解更多內容.)

image.png

對于習慣了iOS開發的同學,可能會對React Native中組件的生命周期很困惑。在iOS中有一個ViewDidLoad來初始化,那么在RN中,又是在哪里呢?

一、看圖分析

在下圖中描述了React Native中組件的生命周期,我們可以根據其中的執行順序在對應的函數中做對應的操作。

image

React Native組件的生命周期大致上可以劃分為

實例化階段

、

存在階段

銷毀階段

,其中最常用的為

實例化階段

,該階段就是組件的構建、展示時期,需要我們根據幾個函數的調用過程,控制好組件的展示和邏輯的處理。

二、實例化階段函數功能分析

getDefaultProps

該函數用于初始化一些默認的屬性,通常會將固定的內容放在這個函數 中進行初始化和賦值;

    在組件中,可以利用

this.props

獲取在這里初始化它的屬性,由于組件初始化后,再次使用該組件不會調用getDefaultProps函數,所以組件自己不可以自己修改props(即:props可認為是只讀的),只可由其他組件調用它時在外部修改。

getInitialState

該函數是用于對組件的一些狀態進行初始化;

   由于該函數不同于getDefaultProps,在以后的過程中,會再次調用,所以可以將控制控件的狀態的一些變量放在這里初始化,如控件上顯示的文字,可以通過

this.state

來獲取值,通過

this.setState

來修改state值, 比如:

<pre style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">

this.setState({
activePage: activePage,
currentX: contentOffSetX
});

</pre>

注意:

一旦調用了this.setState方法,組件一定會調用render方法,對組件進行再次的渲染,不過,如果React框架會自動根據DOM的狀態來判斷是否需要真正的渲染。

componentWillMount

相當于OC中的ViewWillAppear方法,在

組件將要被加載在視圖上之前調用,功能相對較少。

render

render是一個組件中必須有的方法,本質上是一個函數,并返回JSX或其他組件來構成DOM,和Android的XML布局類似,注意:

只能返回一個頂級元素

;

   此外,在render函數中,只可通過

this.state

this.props

來訪問在之前函數中初始化的數據值 。

componentDidMount

在調用了render方法后,組件加載成功并被成功渲染出來以后,所要執行的后續操作,一般會在這個函數中處理網絡請求等加載數據的操作;

   因為UI已經成功被渲染出來, 所以放在這個函數里進行請求操作,不會出現UI上的錯誤。

  下圖是利用了fetch API來異步請求Web API來加載數據:
image

三、存在期階段函數功能分析

componentWillReceiveProps

指父元素對組件的props或state進行了修改

shouldComponentUpdate

一般用于優化,可以返回false或true來控制是否進行渲染

componentWillUpdate

組件刷新前調用,類似componentWillMount

componentDidUpdate

更新后的hook

四、銷毀期階段函數功能分析

   用于清理一些無用的內容,如:點擊事件Listener,只有一個過程:

componentWillUnmount

****五、常用知識點分析****

****5.1 this.state ****

    開發中組件免不了要與用戶互動,React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然后用戶互動,導致狀態變化,從而觸發重新渲染 UI。

   舉個例子:
image
   當用戶點擊組件,導致狀態變化, **this.setState**  方法就修改狀態值,每次修改以后,自動調用  **this.render** 方法,再次渲染組件。

  可以把組件看成一個“狀態機”. 根據不同的status有不同的UI展示。只要使用setState改變狀態值,根據diff算法算出來有差以后,就會執行ReactDom的render方法,重新渲染頁面。

注意:由于 this.props 和 this.state 都用于描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就不再改變的特性,而 this.state 是會隨著用戶互動而產生變化的特性。

5.2 獲取真實的DOM節點

在React Native中,組件并不是真實的 DOM 節點,而是存在于內存之中的一種數據結構,叫做虛擬 DOM (virtual DOM)。

  只有當它插入文檔以后,才會變成真實的 DOM 。

  根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然后再將實際發生變動的部分,反映在真實 DOM上,這種算法叫做 DOM diff,它可以極大提高網頁的性能表現。

 但是,有時需要從組件獲取真實 DOM 的節點,這時就要用到

ref

屬性;

 下圖通過一個案例來演示:
image

運行結果如下:

image
   上面代碼中,組件 View 的子節點有一個文本輸入框,用于獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。為了做到這一點,文本輸入框必須有一個 ref屬性,然后 this.refs.[refName] 就會返回這個真實的 DOM 節點。

  需要注意的是,由于 

this.refs.[refName]

屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個屬性,否則會報錯。上面代碼中,通過為組件指定 Click 事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件之后,才會讀取

this.refs.[refName]

屬性。

六、案例實操

案例主要技術點:

充分利用了RN生命周期的鉤子函數,實現界面刷新。

1.1 利用控件的索引index計算出控件所在的行號和列號

1.2 利用列號計算控件的x值

1.3 利用行號計算控件的y值

案例思路截圖:

image

案例核心代碼:

image
image
image

****案例運行效果截圖:****

image

八、總結

React Native組件的生命周期,經歷了Mount->Update->Unmount這三個大的過程,即從創建到銷毀的過程,結合OC中的開發經驗,我們在以上的基礎上應該可以快速的上手React Native的開發。

九、引用

9.1 什么是DOM Diff算法

   Web界面由DOM樹來構成,當其中某一部分發生變化時,其實就是對應的某個DOM節點發生了變化。在React中,構建UI界面的思路是由當前狀態決定界面。前后兩個狀態就對應兩套界面,然后由React來比較兩個界面的區別,這就需要對DOM樹進行Diff算法分析。

   即給定任意兩棵樹,找到最少的轉換步驟。但是標準的的Diff算法復雜度需要O(n^3),這顯然無法滿足性能要求。要達到每次界面都可以整體刷新界面的目的,勢必需要對算法進行優化。這看上去非常有難度,然而Facebook工程師卻做到了,他們結合Web界面的特點做出了兩個簡單的假設,使得Diff算法復雜度直接降低到O(n)
  1. 兩個相同組件產生類似的DOM結構,不同的組件產生不同的DOM結構;

  2. 對于同一層次的一組子節點,它們可以通過唯一的id進行區分。

    算法上的優化是React整個界面Render的基礎,事實也證明這兩個假設是合理而精確的,保證了整體界面構建的性能。
    

9.2 ES5和ES6的差異化?

   es5,es6 都是對 ecmascript規范的補充,es5已經大規模使用了,es6目前可能在個別平臺存在瀏覽器兼容性問題; 其中箭頭函數()=>()是ES6獨有的。

區別1:創建組件

   組件是一個自定義的js對象,在es5中使用React.createClass();在es6中必須繼承React.component,然后進行創建。

ES5的寫法:

image

ES6的寫法:

image

區別2:組件的屬性props

在ES6中,其為屬性:defaultProps(可以標識static定義在class內,也可以定義在class外),而

在ES5中,其為方法:getDefaultProps: function(){return {name:value}};

ES5:

image

ES6:

image

區別3:

組件的狀態state

ES5:

image

ES6:

image
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容