ref: https://react.docschina.org/docs/reconciliation.html
前提
- 兩個不同類型的元素將產(chǎn)生不同的樹。
- 通過渲染器附帶key屬性,開發(fā)者可以示意哪些子元素可能是穩(wěn)定的。
算法復(fù)雜度
- 廣度優(yōu)先的算法比較 , O(n)
協(xié)調(diào)(Reconciliation)算法
- 不同類型的元素
- 每當(dāng)根元素有不同類型,React將卸載舊樹并重新構(gòu)建新樹。從<a>到<img>或從<Article>到<Comment>,或從<Button> 到 <div>,任何的調(diào)整都會導(dǎo)致全部重建
- 相同類型的DOM元素
- 當(dāng)比較兩個相同類型的React DOM元素時,React則會觀察二者的屬性,保持相同的底層DOM節(jié)點(diǎn),并僅更新變化的屬性
- 相同類型的組件元素
- 當(dāng)組件更新時,實(shí)例仍保持一致,以讓狀態(tài)能夠在渲染之間保留。React通過更新底層組件實(shí)例的props來產(chǎn)生新元素,并在底層實(shí)例上依次調(diào)用componentWillReceiveProps() 和 componentWillUpdate() 方法.
- 遞歸子節(jié)點(diǎn)存在的問題
- 默認(rèn)時。當(dāng)遞歸DOM節(jié)點(diǎn)的子節(jié)點(diǎn),React僅在同一時間點(diǎn)遞歸兩個子節(jié)點(diǎn)列表,并在有不同時產(chǎn)生一個變更。 這就導(dǎo)致當(dāng)在最后插入一個新的節(jié)點(diǎn)時,轉(zhuǎn)換效果非常好,因?yàn)榍懊娴墓?jié)點(diǎn)都沒有變化,故不需要重新渲染,如:
<ul> <li>first</li> <li>second</li> </ul> <ul> <li>first</li> <li>second</li> <li>third</li> </ul>- 當(dāng)在最開始的位置插入新的元素時,React會調(diào)整每個節(jié)點(diǎn),因?yàn)閷Ρ鹊慕Y(jié)果是每個節(jié)點(diǎn)都變化了。如:
<ul> <li>Duke</li> <li>Villanova</li> </ul> <ul> <li>Connecticut</li> <li>Duke</li> <li>Villanova</li> </ul> - Keys 屬性解決遞歸子節(jié)點(diǎn)出現(xiàn)的問題
- 當(dāng)子節(jié)點(diǎn)有key時,React使用key來匹配原本樹的子節(jié)點(diǎn)和新樹的子節(jié)點(diǎn). 如:
<ul> <li key="2015">Duke</li> <li key="2016">Villanova</li> </ul> <ul> <li key="2014">Connecticut</li> <li key="2015">Duke</li> <li key="2016">Villanova</li> </ul>- 現(xiàn)在React知道帶有'2014'的key的元素是新的,并僅移動帶有'2015'和'2016'的key的元素。
- Note:
- Key 屬性在通常使用是一般選擇ID屬性。
- key必須在其兄弟節(jié)點(diǎn)中是唯一的,而非全局唯一。
- 盡量不要使用數(shù)組的index作為key值,因?yàn)楫?dāng)元素重新排序時會引發(fā)不確定的問題,且性能下降。
- Keys應(yīng)該是穩(wěn)定的,可預(yù)測的,且唯一的。不穩(wěn)定的key(類似由Math.random()生成的)將使得大量組件實(shí)例和DOM節(jié)點(diǎn)進(jìn)行不必要的重建,使得性能下降并丟失子組件的狀態(tài)。