1、state 數據 2、jsx模板 3、生成虛擬dom(虛擬DOM就是一個js對象,用它來描述真實DOM) ['div', {id:'abc'}, ['span', {}, 'hello world']] 通過這樣的一個js對象,我們就可以表述上面的dom結構了 4、用虛擬dom的結構,生成真實的dom,來顯示 <div id='abc'><span>hello world</span></div> 5、state發生變化 6、新的虛擬dom(極大的提升了性能) ['div', {id:'abc'}, ['span', {}, 'bye bye']] 7、比較原始虛擬DOM和新的虛擬DOM的區別,找到區別是span中的內容(極大的提升了性能) 8、直接操作DOM,改變span中的內容
如圖,diff算法有個很重要的概念,叫做同級比較,首先會比較最頂層的虛擬dom節點是否一致,假設一致,再去比較下一個節點。假設第一層虛擬dom不一致,這個時候怎么辦呢?這個時候react就不會往下比了,他會原始的虛擬dom下面的節點全部刪除掉,重新生成一遍節點下面的所有dom,然后用重新生成的dom,替換原始頁面的dom,也就是只比對一層dom,大家可能會想,這不是性能很低嗎?假設第一層節點不同,下面的節點都相同,豈不是下面的節點都沒法復用了,確實是這樣的,雖然會造成一些dom節點的渲染浪費,但是這種比對有什么好處呢?我們說同層比對,帶來的算法非常的簡單,只要一層一層的做對比就行了,算法簡單,帶來的好處就是比對的速度會非常的快,所以可能會造成重新渲染的一些浪費,但大大減少了去比對的算法上的性能消耗。所以采用了同層比對的算法。
再如圖,假設我有1個數組,數組里面有5個數據,然后在頁面第一次渲染的時候,我會把這個5個數據映射成5個虛擬dom節點,生成一個小的虛擬dom樹,接着我又往數組里面增加一些內容,於是數據發生變化,會生成一個新的虛擬dom樹,然后會進行一個比對,就是圖左上下進行比對,如果每個虛擬dom沒有一個key值,就沒有一個自己的名字,當作兩個虛擬dom樹比對的時候,節點和節點之間的關系就很難被確定,比如下面的第一個是跟上面的第一個是一個即誒單,還是跟第二個是一個節點,很難做判斷,所以得做兩層循環的一個比較,這樣比較起來就很麻煩了,也比較耗性能,現在加入在給虛擬dom循環的時候,我們可以給每一個節點起一個名字多好,如圖右,虛擬dom根據key值做關聯,只要找到對應的名字一樣的節點是否相同,極大的提高了react的性能。這里就是為什么不要用index,如果key值是index的話,就沒法保證在原始的虛擬dom樹上,他的key值和虛擬dom樹上的key值一致了。舉個例子,比如一個數組