1. 程式人生 > >react框架設計原理及生命週期

react框架設計原理及生命週期

1、ReactJS的背景
1、react是Facebook為實現其內部廣告系統專案設計的一種前端介面構建方式
2、前端工程師的職責就是把邏輯資料實時反應到view層,既然涉及到vie層,  
   那就涉及到dom樹。而大家都知道,複雜或者頻繁的操作dom通常是造成效能  
   不好的地方。
3、所以設計react的地方就是其虛擬dom

2、ReactJS的設計原理

react的設計原理就是其引入的虛擬dom機制:
    1、react用javascript在瀏覽器端實現了一套虛擬dom api。
    2、基於react開發的時候所有的dom構造都是基於虛擬dom進行的  
    3、每當有state更改的時候,react就重新render一整套虛擬dom樹,  
        react機制會將當前的整個dom樹和上一次的dom樹進行對比  
        取到diff,進行真實的dom更改。
    4、其實state也有一部分實現的是資料、html片段繫結,  
        直接更新的資料是包含的
    其實說到這裡,往深一點考慮就是react的虛擬dom的diff演算法
從大層面上來講

react資料驅動更新dom樹

深層次一點就是react的diff演算法是怎麼理解的。
    錯誤的見解:我曾經以為diff演算法,就是深層次的diff,演算法運算時只比較  
            不同的。但其實當時淺顯的想法,確實是diff運算的結果,但不是  
            diff運算的演算法。
    1、tree diff  
        也叫層級diff,

這裡寫圖片描述

針對上圖
    React對Virtual DOM樹進行層級控制,只會對相同層級的DOM節點進行比  
    較,即同一個父元素下的所有子節點,當發現節點已經不存在了,則會刪除掉  
    該節點下所有的子節點,不會再進行比較。這樣只需要對DOM樹進行一次遍  
    歷,就可以完成整個樹的比較。
    即使說a節點以及他的子節點被移動,但是react只關注同級比較,在第二層  
    把a及其子節點刪了,在第三層再重新建立,所以diff運算量大,影響效能  
    不建議setState直接更改樹的結構。最好是state顆粒度小,只改變樹中  
    的某一個小的節點,那麼diff的時候只會深度比較這一個小節點。
    2、componnet diff

這裡寫圖片描述

    假如說因為某個條件切換,所以要顯示不同的元件。
    1、比較兩個元件的型別(D和G)
    2、如果(D和G)不是同一型別,進行diff演算法,分析會影響效能  
       直接刪掉上一個虛擬dom元件。 重新建立新的元件。
       如果是同一型別的元件,會按照層級策略深層對比每個節點。
    3、element diff
        精確的對屬於同一層級的節點diff時,提供了3種節點操作,分別為INSERT_MARKUP(插入),MOVE_EXISTING(移動),REMOVE_NODE(刪除)。
    如果同一層級,沒有這個新節點會新增插入
    如果同一層級,如果有新節點,但是屬性不一樣,會複用節點,賦值屬性
    如果同一層次,舊dom有,新dom沒有,會刪除這個節點。
總結:setState()觸發一次元件重繪,其實就是虛擬dom重新生成,除非在  
shouldComponentUpdate()中實現了一些條件渲染邏輯。來允許和阻止是否需要  
呼叫指定元件的 render 方法。其實這個深入邏輯就是他觸發了render,只是是  
否觸發了內部的diff演算法,return false 的時候,不diff,render出來的新  
舊dom一樣。diff演算法的複雜度為0。

這裡寫圖片描述

React的核心
     1、使用元件定義介面,是一個View層的前端庫,介面可能由  
        一個或者多個元件構建而成
    react的虛擬DOM是如何反映到真實的DOM樹上的?
        解答:首次渲染大量DOM時,由於多了一層虛擬DOM的計算,會比  
        innerHTML插入慢。虛擬DOM可以確保只對介面上真正變化的部分進行  
        實際的DOM操作。
             比如:
             替換節點就需要調原生JS物件的repaceChild()介面;  
             對於修改屬性,則要調setAttribute()介面等等。
3、react 生命週期

這裡寫圖片描述