有没有办法让 React 为孩子自动定义“键”?

2024-05-21

我正在学习 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 不能使用更智能的自动键呢?答案是,要做到这一点,实际上只有两种选择,而且都不是理想的选择:

  1. 他们可以对您的应用程序的结构做出某些假设。在您的简短示例中,对于人类来说,显然应该根据文本内容来匹配段落。但这并不一定在所有情况下都是如此,并且很难将这种逻辑扩展到具有自定义元素、大量道具、嵌套子项等的更复杂场景。

  2. 他们可以使用一种奇特的通用比较算法,但就 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(使用前将#替换为@)

有没有办法让 React 为孩子自动定义“键”? 的相关文章

随机推荐

  • 将 div 设置为 post 方法结果页面的目标容器

    我有一个 div 标签 也分为两个 div 这是代码 div div div div
  • Java HashMap 嵌套泛型与通配符

    我正在尝试创建包含自定义类的不同子类的哈希集的哈希映射值的哈希映射 如下所示 HashMap
  • 浏览器中缺少 Angular 12 源地图

    我们已经升级到角12最近遇到一个问题 即浏览器源映射丢失 因此我们无法调试我们的组件文件 因为没有任何组件文件 谁能建议我缺少什么 Angular 12 更改了默认的 ng build 以使用 生产 配置 你想要 sourceMap 所以尝
  • 如何在qt中创建正确的退出按钮

    我正在尝试创建一个退出按钮来正确关闭我在 QT 中制作的 GUI 我尝试通过以下方式执行此操作 include
  • Spring @Validated 在服务层

    Hej 我想使用 Validated group Foo class 在执行方法之前验证参数的注释 如下所示 public void doFoo Foo Validated groups Foo class foo 当我将此方法放入 Spr
  • 我应该把 .gitignore 放在哪里才能影响所有项目?

    我应该在哪里放置一个 gitignore文件以便我的所有项目都使用这些设置 我尝试了各种文件夹 只有将其放入项目文件夹中才能使其正常工作 但是设置 当然 仅应用于该项目 而不是我的其他项目 git 包含一个 全局 配置选项 可以告诉它在启动
  • FLAG_ACTIVITY_REORDER_TO_FRONT 被忽略

    我有一个包含项目列表的 FragmentActivity 当应用程序处于后台时 可以推送该项目列表 发生这种情况时 我想创建一个状态栏通知并提醒用户更新 当用户单击通知时 活动应重新排序到前面并显示在屏幕上 同时在列表底部显示新项目 所以我
  • 简单的WPF + MVVM绑定

    我有一个名为MyWindow源自于Window 我使用 MVVM 模式 因此在代码隐藏中我有以下字段 public MyViewModel ViewModel new MyViewModel ViewModel包含一个集合Person 我想
  • Bash 脚本:自动为 mpeg-dash 进行 ffmpeg 编码

    我正在编写一个 bash 文件来创建视频编码和串联 以供 dash 实时流媒体使用 基本上 它读取输入视频文件夹 将所有视频编码为三种分辨率格式 然后将它们连接起来创建三个适应集 DIAGRAM 该脚本检查 fps 一致性 如果输入不是 1
  • scipy 将一个稀疏矩阵的所有行附加到另一个稀疏矩阵

    我有一个 numpy 矩阵 想在其中附加另一个矩阵 这两个矩阵的形状为 m1 shape 2777 5902 m2 shape 695 5902 我想将 m2 附加到 m1 以便新矩阵的形状为 m new shape 3472 5902 当
  • 我的CSS出了什么问题?活动链接不改变颜色

    我无法让我的 WordPress 菜单活动链接保持红色 我添加了我认为与导航相关的 CSS 还有正文等 以防影响问题 感谢您的帮助 body font family Helvetica Neue sans serif font size 1
  • 错误“没有可用于此声明的持久卷,并且未设置存储类别”

    是需要在nodes中手动创建目录还是pv自动创建 这是我的 pv 和 pvc 文件 我看到这个错误 没有可用于此声明的持久卷 并且未设置存储类别 如何解决这个问题 kind PersistentVolume apiVersion v1 me
  • 从 Angular 4 中的选择选项获取价值

    如何从 Angular 4 中的 select 选项获取值 我想将它分配给 component ts 文件中的一个新变量 我已经尝试过但没有输出任何内容 你也可以使用 ngModel 来做到这一点吗 组件 html
  • Android 中有没有办法获取 SD 卡大小?

    欢迎大家 我已经在 Stackoverflow 和 google 上尝试过与此相关的每个问题 但没有一个有效 我已经尝试过类似下一个链接的操作 但它返回的内容与内部存储相同 如何获取外部存储 SD 卡的大小 带安装的 SD 卡 https
  • 在 .NET 并发线程之间传递数据的最佳方式是什么?

    我有两个线程 一个需要轮询一堆单独的静态资源以查找更新 另一种需要获取数据并将其存储在数据库中 线程1如何告诉线程2有东西要处理 如果数据块是独立的 则将数据块视为要由线程池处理的工作项 使用线程池和QueueUserWorkItem将数据
  • 如何在 Windows 64 上安装 NumPy?

    NumPy 安装程序在注册表中找不到 python 路径 无法安装 需要 Python 2 5 版本 但在注册表中未找到该版本 OK 我必须修改注册表吗 我已经修改了 PATH 以指向Python25安装目录 我可以检查一下您使用的是什么安
  • 如何缓存 twitter api 结果?

    我想缓存 twitter api 结果的结果并将其显示给用户 缓存结果的最佳方法是什么 我正在考虑根据时间限制将结果写入文件 可以吗 还是应该使用任何其他方法 最重要的是 理想的缓存时间是多少 我想显示来自 twitter 的最新内容 但
  • OAuth2.0 redirect_uri 的参数值无效:缺少方案

    我正在将 Oauth 2 0 流程用于部署在 GCP 中的 appengine Web 应用程序 我正在使用 IAP 我有一个使用 Cloud KMS 加密的有效 cliend secret 文件 但我遇到了以前没有的错误 oauthlib
  • 扫描 PHP 上传的病毒

    我目前正在使用以下代码来扫描作为申请表的一部分上传的文件 safe path escapeshellarg dir file command usr bin clamscan stdout safe path out int 1 exec
  • 有没有办法让 React 为孩子自动定义“键”?

    我正在学习 React 我偶然发现了 动态儿童 的这个怪癖 带有代码示例的序言 Render Pass 1