Reactjs 是否有一种方法可以让您对“自动定义”做出反应;“钥匙”;给孩子们?

Reactjs 是否有一种方法可以让您对“自动定义”做出反应;“钥匙”;给孩子们?,reactjs,Reactjs,我正在学习如何反应,我偶然发现了“充满活力的孩子”的这种怪癖 序言和代码示例: //渲染过程1 第1款 第2款 //渲染过程2 第2款 在第二个render()过程中,vdom扩散的工作方式似乎是删除第二个子项,然后将第一个子项中的文本转换为“段落2”。速度很快,但如果需要状态保持不变,您会看到奇怪的事情发生。。。第二个孩子 所以React建议使用。现在,vdom差分将毫无意外,您将看到状态在renders()中得到保留 我的问题是:有没有办法让React自行设置“键”,而不是按照他们建议的方

我正在学习如何反应,我偶然发现了“充满活力的孩子”的这种怪癖

序言和代码示例:

//渲染过程1
第1款

第2款

//渲染过程2 第2款

在第二个
render()
过程中,vdom扩散的工作方式似乎是删除第二个子项,然后将第一个子项中的文本转换为“段落2”。速度很快,但如果需要状态保持不变,您会看到奇怪的事情发生。。。第二个孩子

所以React建议使用。现在,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>
//渲染过程1

第1段

第2段

//渲染过程2

第2段

这就是为什么您会看到第一个元素的文本被转换,但正如您所注意到的,这并不总是最佳结果。那么为什么不能使用更智能的自动钥匙呢?答案是,要做到这一点,实际上只有两种选择,而这两种选择都不理想:

  • 他们可能会对你的应用程序的结构做出某些假设。在您的简短示例中,很明显,段落应该根据其文本内容进行匹配。但这并不一定在所有情况下都是正确的,而且很难将这种逻辑扩展到具有自定义元素、大量道具、嵌套子项等的更复杂场景

  • 他们可以使用一种奇特的通用差分算法,但这些算法在React非常认真的性能方面可能会非常昂贵。正如React所说:

    有许多算法试图找到转换元素列表的最小操作集。Levenshtein距离可以通过在O(n2)中的单元素插入、删除和替换找到最小值。即使我们使用Levenshtein,也不会发现节点何时移动到另一个位置,而这样做的算法的复杂性要差得多

  • 因此,无论哪种方式,“自动密钥分配”的任何好处都伴随着一系列缺点。最后,这真的不值得,特别是考虑到在大多数情况下手动分配关键点并不是那么困难或麻烦。从同一文档页面的下一页开始:

    实际上,找到一把钥匙并不难。大多数情况下,您将要显示的元素已经具有唯一的id。如果不是这样,您可以向模型中添加新的id属性,或者对内容的某些部分进行散列以生成密钥。请记住,密钥只需在其同级中唯一,而不是全局唯一


    您可以调用
    React.Children.toArray
    自动定义键

    感谢@hopper的全面回答。是的,我想每次只写

    {item.message}

    并不难。我想我们可以假设React的人认为速度优势证明了这一点不便。但是在生成组件时随机字符串分配又如何呢?为什么这样不好?不确定为什么react不能提供一种显式生成密钥的简单方法。这样一来,人们就可以获得钥匙和人类判断力的所有好处,而不用被迫想出一些东西来用作钥匙。