javascript – 在React中循环向JSX元素添加密钥的不同方法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 在React中循环向JSX元素添加密钥的不同方法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3938字,纯文字阅读大概需要6分钟。
内容图文
我已经做了一年多的反应.我主要使用.map,.forEach,.filter或使用Object.keys和Object.values迭代一个数组(如果它是一个对象).
但是为jsx元素添加唯一键的不同方法有哪些.以下是我到目前为止所习惯的
使用数据中的唯一ID作为关键道具的关键:
const data= [{"id": "01", "name": "abc"}, {"id": "02", "name": "xyz"}];
render(){
const items = data.map(item => {
return <span key={item.id}>{item.name}</span>;
}
return(
<div>
{items}
</div>
)
}
使用索引作为关键道具的关键:
const data= [{"id": "01", "name": "abc"}, {"id": "02", "name": "xyz"}];
render(){
const items = data.map((item, i) => {
let keyValue = i+1;
return <span key={keyValue}>{item.name}</span>;
}
return(
<div>
{items}
</div>
)
}
除了我上面提到的以及最有效和推荐的方法之外,还有其他方法可以为jsx元素添加唯一键吗?
解决方法:
首先,避免使用随机密钥.
写密钥有很多种方法,有些方法比其他方式更好.
要了解我们选择的密钥如何影响性能,有必要了解React的协调算法.
https://reactjs.org/docs/reconciliation.html
tl; dr引入一种启发式,用于比较虚拟DOM树以进行此比较O(n),其中n为此VDOM树的节点.这种启发式可以分为以下两点:
>不同类型的组件将创建一个新树:这意味着,在将旧树与新树进行比较时,如果协调程序遇到节点确实更改了其类型(例如< Button /> to< NotButton /> ;),将导致我们的Button与其子项一起卸载,并且NotButton也将与其子项一起安装.
>我们可以提示React如何在VDOM上保留实例,避免重新创建它们.这些提示由我们提供密钥:在确定是否应保留节点中的实例(因为其类型保持不变)之后,协调程序将迭代该节点的子节点以进行比较.
现在说我们有这个:
<div>
<Button title="One" />
<Button title="Two" />
</div>
我们想在下一个渲染中为DOM添加一个Button,比如说
<div>
<Button title="Zero" />
<Button title="One" />
<Button title="Two" />
</div>
算法将如下:
>比较< divs>在两个VDOM中.由于它们具有相同的类型,因此我们不需要重新创建新树.道具是相同的,因此此时没有适用于DOM的更改.
> Button One与Zero比较. Reconciler检测到这是一个道具更改,然后使用此标题更新DOM.
> Button Two与One比较. Reconcilier还会在此处检测道具更改并使用DOM来编写此更改.
>检测到新的Button被添加为最后一个子项,因此在VDOM创建一个新的Button实例并在DOM处写入此更改.
请注意,它们在DOM上有许多操作,因为它通过索引比较组件.
现在,我们可以通过告知我们的协调程序应该重用这些实例来解决此问题.现在,让我们有这个:
<div>
<Button title="One" key="One" />
<Button title="Two" key="Two" />
</div>
我们想在下一个渲染中为DOM添加一个Button,比如说
<div>
<Button title="Zero" key="Zero" />
<Button title="One" key="One" />
<Button title="Two" key"Two" />
</div>
算法将如下:
>比较< divs>在两个VDOM中.由于它们具有相同的类型,因此我们不需要重新创建新树.道具是相同的,因此此时没有适用于DOM的更改.
>成为孩子的第一个孩子.调和者说,这是一个按钮. ‘并且有一把钥匙'(‘一’).然后,在新的儿童名单中寻找关键相同的孩子. “哦,我遇到了!”但是,调和者意识到它的道具没有变化.然后,这个不需要DOM操作.
>第二个Button会出现相同的情况,它将通过键而不是索引进行比较.意识到它是相同的实例并且没有更改任何道具,因此React决定不对DOM应用更改.
>对于带有“零”键的按钮,由于没有相同键的子项,因此意识到应该在VDOM上创建实例,并且应该在DOM上编写此更改.
因此,通过可预测内容使用密钥有助于协调程序对DOM执行较少的操作.健康键是那些可以从被映射的对象推断出来的键,如名称,id或甚至是url,如果我们正在将url转换为< imgs />.
那么key = index呢?将无效,因为默认情况下,协调程序按位置(即其索引)进行比较.
这些键应该是全球唯一的吗?不必要.这些在兄弟姐妹中应该是唯一的,因此协调者可以在节点的子节点迭代时区分它们.
随机键怎么样?应不惜一切代价避免这些.如果一个键在每个渲染上发生变化,这将使React破坏并在VDOM上创建实例(因此,在DOM上进行额外的写入),因为在新的子节点中找不到具有键的组件,而是新的子节点具有相同的类型.
如果渲染输出是这样的
<div>
<Button key={randomGenerator()} />
</div>
然后,每次执行渲染(例如,由于道具/状态更改,或者即使它的父级正在重新渲染并且我们的shouldComponentUpdate返回true),也会生成一个新的randomGenerator()键.这将是:
‘嘿!我找到了一个带有F67BMkd ==键的Button,但没有找到下一个.我会删除它.
‘哦!我遇到了一个带有SHDSA 5键的按钮!让我们创建一个新的’.
每当协调程序告知应删除和卸载实例时,其内部状态将丢失;即使我们再次安装它.
在这种情况下,VDOM的实例不会被保留.
按钮是相同的,但协调员在DOM上弄得一团糟.
希望能帮助到你.
内容总结
以上是互联网集市为您收集整理的javascript – 在React中循环向JSX元素添加密钥的不同方法全部内容,希望文章能够帮你解决javascript – 在React中循环向JSX元素添加密钥的不同方法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。