react渲染
1.生成虛擬dom
createElement的作用就是生成虛擬dom。虛擬dom到底是個啥,其實它就是個javascript對象~,這個對象的屬性有props,vType,type, 而props也是個對象,它有children屬性也有其他的,比如className,onClick之類的。
2.虛擬dom轉化成dom
虛擬dom的vtype是3的時候對應的type是自定義組件,vtype是2的時候是對應的type是div之類的瀏覽器原生組件。
涉及到一個遞歸函數initVnode,initVnode接收一個參數:虛擬dom,返回一個參數dom。
a.如果是vtype等於3那麽對應的type就是自定義的組件的構造函數,這時候,需要new一個自定義組件的對象,然後調用這個對象的render方法,
這個組件的render方法返回的仍然是個虛擬dom。 這時候就輪到遞歸上場了,調用自己去把這個虛擬dom轉化成dom節點,並返回這個節點。
b.如果是vtype等於2,那麽對應的type是瀏覽器原生組件,這個時候就document.createElement(type),這裏children有可能是個虛擬dom數組,
遍歷這個數組,用initVnode把虛擬dom轉化成dom節點,再把dom節點appendChild到他們的父組件上,並返回父組件。
當調用render方法時,render會去調用一個map方法,根據傳入參數的不同,把被render的對象分為以下三類:
* 文本
* 原生
* 自定義標簽
文本
對於文本,React會實例化一個文本節點的對象,並且調用該對象的mount方法。在這個mount方法中,把文本放到一個span
中,調用容器組件的innerHTML
,進行渲染。
原生標簽
對於原生標簽,React會實例化一個處理原生標簽的對象,並且調用該對象的mount方法。在這個mount方法中,拼接一個字符串,並且不斷遞歸上面的map方法,最後把拼接好的字符串放到容器組件的innerHTML
中,進行渲染。
自定義標簽
這個應該是大家最好奇的。自定義標簽雖然叫標簽,其實就是一個類。實例化一個處理自定義標簽的對象後,首先React會處理自定義標簽的生命周期方法,然後再次遞歸調用子組件的render方法進而調用map方法,直至把自定義標簽分解為前兩種標簽。
更新
在調用this.setState()
以後,也是調用了一個map方法,根據傳入參數不同,依然把要更新的標簽分為文本、原生標簽、自定義標簽三類。具體處理過程如下。
文本
文本節點處理很簡單,判斷要更新後的文本與當前文本是否===
,不是全等就刪除原來文本,插入新文本。
自定義標簽
對於自定義標簽,首先根據對象的引用、key是否相同,判斷是否需要更新。如果需要更新,就繼續調用上述map方法進行子組件的更新。又是一個遞歸。但是註意,這裏的map方法和渲染部分的map方法不是一個方法喲。
原生標簽
對於原生標簽,首先更新組件的屬性,然後update子樹,用diff算法來比較新的子樹與目前標簽的子樹的不同,形成一個差異樹,然後用patch方法,把這個差異樹更新到真正的DOM樹上。
react渲染