React Reconciliation

React Reconciliation

一.什么是Reconciliation

  1. 每次render的時候,React都會產生一棵由React元素組成的樹,這個樹形結構就是所謂的虛擬DOM,下次render的時候又會產生新的一顆樹,對比這兩棵樹的不同的過程,就是調和,即Reconciliation

二.對比過程,分為以下幾種情況

1. 根節點類型不同的情況
  • 如果根節點就不同,如下的div變成了span,那么對比的開銷太大了,所以React選擇了重建,會將原有的樹卸載,再將新的樹裝載
<div>
  <Counter />
</div>

<span>
  <Counter />
</span>
2.根節點類型相同的情況
  • 如果是根節點相同的情況下,只會更改有變化的部分

  • 當節點類型是HTML元素類型時(如span,p,div等)

如下,只會更改color變化的值和div里變化的值

<div style={{color: 'red', fontWeight: 'bold'}}>hello world</div>

<div style={{color: 'green', fontWeight: 'bold'}}>good bye</div>
  • 當節點類型是React組件類型時

    如下,React并不知道如何去更新DOM,因為這些邏輯還在React組件當中,所以只能去更新props的值,引發這個組件的更新過程,實現對子元素的遞歸

    <Todo text="old">
    
    <Todo text="new">
    
3.多個同級元素的情況
  • 有時候我們會遇到增加同級元素的情況,這里以HTML元素為例,React組件也是一樣
  • 如果是在最下方插入的情況,那么事情沒那么糟糕,因為React會去對比每個元素,first對比fisrtsecond對比second,然后發現多了一個third,那么就在原有的基礎上加上這個元素
  • 但是如果是在最上方插入的情況,React使用的O(n)復雜度的算法會逐個對比,即first對比thirdsecond對比first,然后發現多了一個second,這樣的話,本來只是新增一個元素的情況,會變成全部元素都要修改
//最下方插入

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

//最上方插入

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>third</li>
  <li>first</li>
  <li>second</li>
</ul>
  • 有沒有解決上面最上方插入所帶來的問題的方法呢,答案是使用唯一的Key
  • 當使用了唯一的Key以后,React會知道,firstsecond是原來的那個元素,現在新增的只是third元素,當然這里有很重要的一點,這個Key必須是穩定不變的,試想一下,如果原先first是1,second是2,后面third是1,first是2,second是3,這樣的話,從上到下一一對比,每個元素又要重新渲染,就失去了Key的意義,導致不必要的元素重新創建和子組件中的狀態丟失【1】
//最上方插入

<ul>
  <li key={1}>first</li>
  <li key={2}>second</li>
</ul>

<ul>
  <li key={0}>third</li>
  <li key={1}>first</li>
  <li key={2}>second</li>
</ul>

三.代碼優化思考

1.以前早就聽說過不要用數組下標作為Key,但是現在才對Key值需要唯一且穩定有了深刻理解,具體理解見上面的【1】,數組下標作為Key也不是一棒子打死,當這些元素不需要重新排序的時候,可以采用,當這個元素需要重新排序的時候,就不要用數組下標了

2.也不要用Math.random()作為Key

3..針對React對根節點類型不同的情況的處理,在寫代碼的時候就要避免改變根節點的情況

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容