对账是 React 库的一个内部过程。众所周知,react 应用程序会创建一个虚拟 DOM,然后根据虚拟 DOM 更新应用程序的实际 DOM。 每当 react 收到更新请求时,它首先会创建一个虚拟 DOM,然后使用不同的差异算法将虚拟 DOM 与之前的状态进行比较,然后只有在绝对必要的情况下才这样做, 它将更新 DOM。
尽管 diff 算法和更新 DOM 是 React 核心的内部函数,但了解一些内部函数将有助于我们调整应用程序以最大限度地利用 React 库。
差分算法
让我们看看本章中 react core 应用的一些差异算法。
- 相同类型的元素
- 每当 react 组件将元素从一种类型更改为另一种类型(例如从 div 更改为更具体的 p)时,整个 react 虚拟 dom 树都会发生变化,并触发 DOM 更新。
<!-- Before -->
<div>
<Content />
</div>
<!-- After -->
<p>
<Content />
</p>
在这里,整个元素将得到更新。
- 相同类型的 DOM 属性。
- 当元素类型相同时,react 将检查属性是否存在差异。如果 react 发现属性及其值有任何新的变化,那么它只会更新更改的属性。
<!-- Before -->
<div className="someClass">
<Content />
</div>
<!-- After -->
<div className="someOtherClass">
<Content />
</div>
在这里,只有 DOM 实例的 class 属性会更新。
- 相同类型的 DOM 属性(样式)。
- 当元素属于相同类型并做出反应发现样式属性的差异时,它将仅更新样式的属性。
<!-- Before -->
<div style={{fontFamily: 'Arial'}} />
<p> ... </p>
</div>
<!-- After -->
<div style={{color: 'red', fontFamily: 'Arial'}} />
<p> ... </p>
</div>
在这里,只有 div 元素样式的颜色属性会被更新
- 相同类型的组件元素 - 每当 react 看到相同的 react 组件类型时,它将调用 react 组件的 componentWillUpdate 事件和其他更新事件来更新组件的状态。然后,它将调用组件的 render 方法和算法递归
- 相同类型的子元素的集合 - 每当 react 看到相同类型的子元素集合时,它都会检查元素的差异顺序。因此,如果我们有了新的第一个孩子,那么整个集合都会更新。
<!-- Before -->
<ul>
<li>Peter</li>
<li>Olivia</li>
</ul>
<!-- After -->
<ul>
<li>John</li>
<li>Peter</li>
<li>Olivia</li>
</ul>
在这里,整个元素(ul 元素的子元素)将被更新,因为第一个元素 (li) 是更新的元素。
为了解决这个问题,我们可以引入一个键属性,如下面的代码片段所示。为此,React 有一个特殊的键属性。
<!-- Before -->
<ul>
<li key="1">Peter</li>
<li key="2">Olivia</li>
</ul>
<!-- After -->
<ul>
<li key="3">John</li>
<li key="1">Peter</li>
<li key="2">Olivia</li>
</ul>
总结
React 尝试优化每个版本中的差异算法,以确保更新最少。最少的更新意味着应用程序的性能更好。了解内部并通过遵循最佳实践进行相应的编码,我们可以成倍地提高我们的应用程序性能。