我已经从事反应超过一年了。我主要使用.map,.forEach,.filter或如果对象是Object.keys和Object.values来迭代数组。
但是向jsx元素添加唯一键的不同方法是什么。到目前为止,我已经习惯了以下内容
使用数据中的唯一ID作为键prop的键:
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树与该VDOM树的n个节点进行比较O(n)。这种启发式方法可以分为以下几点:
<Button />
<NotButton />
现在假设我们有这个:
<div> <Button title="One" /> <Button title="Two" /> </div>
我们想在下一个渲染中向DOM添加一个Button,例如
<div> <Button title="Zero" /> <Button title="One" /> <Button title="Two" /> </div>
该算法将如下所示:
<divs>
One
Zero
Two
Button
请注意,它们在DOM上有许多操作,因为它通过索引比较了组件。
现在,我们可以通过告知协调器这些实例应被重用来解决此问题。现在,让我们有这个:
<div> <Button title="One" key="One" /> <Button title="Two" key="Two" /> </div>
<div> <Button title="Zero" key="Zero" /> <Button title="One" key="One" /> <Button title="Two" key"Two" /> </div>
keys
index
因此,通过可预测的内容使用密钥有助于协调器在DOM上执行较少的操作。健康键是可以从正在映射的对象中推断出来的键,例如name,如果要转换为id,url则为,甚至urls为<imgs />。
name
id
url
urls
<imgs />
那key=index呢 将不起作用,因为默认情况下,协调程序会按位置(即其索引)进行比较。
key=index
这些键应该是全局唯一的吗?不必要。这些在兄弟姐妹之间应该是唯一的,因此协调程序可以在节点的子节点进行迭代时区分它们。
随机密钥呢?应不惜一切代价避免这些情况。如果每个渲染上都有一个键更改,这将使React破坏并在VDOM上创建实例(并因此在DOM上进行额外的写操作),因为在新的子级中没有找到带有键的组件,而是一个新的具有相同的类型。
如果渲染输出像
<div> <Button key={randomGenerator()} /> </div>
然后,每次render执行(例如,由于道具/状态更改,或者即使其父级被重新渲染并shouldComponentUpdate返回true),randomGenerator()也会生成一个新密钥。这将像:
render
shouldComponentUpdate
true
randomGenerator()
‘嘿!我找到了一个Button带F67BMkd==钥匙的钥匙,但下一个没有找到。我将其删除。’哦!我遇到了Button一把SHDSA++5钥匙!让我们创建一个新的。
F67BMkd==
SHDSA++5
每当协调程序告诉您应该删除并卸载实例时,其内部状态都会丢失;即使我们再次安装它。在这种情况下,将不会保留VDOM上的实例。
该Button是一样的,但在调解DOM做了一个烂摊子。
希望能帮助到你。