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