概念
DOM diff 就是對比兩棵虛擬 DOM 樹的算法。
當組件變化時轧苫,會得到一個新的虛擬 DOM楚堤,diff 算法對比新舊虛擬 DOM 之后,得到一個 patch含懊,然后 React 用 patch 來更新真實 DOM。
如何對比
- 首先對比兩棵樹的根節(jié)點
- 如果根節(jié)點的類型改變了衅胀,比如 div 變成了 p岔乔,那么直接認為整棵樹都變了,不再對比子節(jié)點滚躯。此時直接刪除對應(yīng)的真實 DOM 樹雏门,創(chuàng)建新的真實 DOM 樹。
- 如果根節(jié)點的類型沒變掸掏,就看看屬性變了沒有
- 如果沒變茁影,就保留對應(yīng)的真實節(jié)點
- 如果變了,就只更新該節(jié)點的屬性丧凤,不重新創(chuàng)建節(jié)點募闲。
- 更新 style 時,如果多個 css 屬性只有一個改變了愿待,那么 React 只更新改變的浩螺。
- 然后同時遍歷兩棵樹的子節(jié)點,每個節(jié)點的對比過程同上仍侥。
列表渲染中的key
- 存在的原因:為了更好地復用dom節(jié)點要出,即列表元素順序變化時依然可以復用。
- 對比規(guī)則:
若舊虛擬DOM中找到了與新虛擬DOM相同的key:
①.若虛擬DOM中內(nèi)容沒變, 直接使用之前的真實DOM农渊。
②.若虛擬DOM中內(nèi)容變了, 則生成新的真實DOM患蹂,隨后替換掉頁面中之前的真實DOM。 - 用index作為key可能會引發(fā)的問題:
(1) 若對數(shù)據(jù)進行:逆序添加砸紊、逆序刪除等破壞順序操作:
會產(chǎn)生沒有必要的真實DOM更新 ==> 界面效果沒問題, 但效率低传于。
(2) 如果結(jié)構(gòu)中還包含輸入類的DOM:
會產(chǎn)生錯誤DOM更新 ==> 界面有問題。
- 如果不存在對數(shù)據(jù)的逆序添加批糟、逆序刪除等破壞順序操作格了,僅用于渲染列表用于展示,使用index作為key是沒有問題的徽鼎。