我正在学习 React,我偶然发现了“动态儿童”的这个怪癖。
带有代码示例的序言:
// Render Pass 1
<Card>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</Card>
// Render Pass 2
<Card>
<p>Paragraph 2</p>
</Card>
在第二render()
通过,似乎 vdom 比较的工作方式是删除第二个子项,然后将第一个子项中的文本转换为“第 2 段”。它很快,但如果你需要状态来坚持,比如……第二个孩子,你会看到奇怪的事情发生!
所以 React 建议使用这些标签的“key”属性 https://facebook.github.io/react/docs/multiple-components.html#dynamic-children。现在,vdom 差异将不再令人意外,您将看到状态得到保留renders()
.
我的问题:有没有办法让 React 自己设置“键”,而不是按照他们建议的方式设置?
不,那里没有。
正如您所观察到的,当没有指定键时,React 的默认行为是使用简单的方法就地更新组件。从功能上讲,这相当于根据元素相对于其兄弟元素的索引指定默认键。在您的示例中,这看起来像:
// Render Pass 1
<Card>
<p key={0}>Paragraph 1</p>
<p key={1}>Paragraph 2</p>
</Card>
// Render Pass 2
<Card>
<p key={0}>Paragraph 2</p>
</Card>
这就是为什么您会看到第一个元素的文本已转换,但正如您所注意到的,这并不总是最佳结果。那么为什么 React 不能使用更智能的自动键呢?答案是,要做到这一点,实际上只有两种选择,而且都不是理想的选择:
他们可以对您的应用程序的结构做出某些假设。在您的简短示例中,对于人类来说,显然应该根据文本内容来匹配段落。但这并不一定在所有情况下都是如此,并且很难将这种逻辑扩展到具有自定义元素、大量道具、嵌套子项等的更复杂场景。
-
他们可以使用一种奇特的通用比较算法,但就 React 非常注重的性能而言,这些算法的成本可能相当高。作为反应调节文件 https://facebook.github.io/react/docs/reconciliation.html#list-wise-diff says:
There are many algorithms that attempt to find the minimum sets of operations to transform a list of elements. Levenshtein distance can find the minimum using single element insertion, deletion and substitution in O(n2). Even if we were to use Levenshtein, this doesn't find when a node has moved into another position and algorithms to do that have much worse complexity.
因此,无论哪种方式,“自动键分配”的任何好处也伴随着一系列缺点。最后,这并不值得,特别是考虑到在大多数情况下手动分配键并不是那么困难或麻烦。从同一文档页面的更下方:
实际上,找到一把钥匙并不难。大多数时候,您要显示的元素已经有一个唯一的 ID。如果不是这种情况,您可以向模型添加新的 ID 属性或对内容的某些部分进行哈希处理以生成密钥。请记住,密钥只需在其同级密钥中唯一,而不是全局唯一。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)