我是新手,但我知道唯一密钥的主要概念。但是,我会得到警告。
下面我有一个项目组件:
class Item extends Component {
state = {}
render() {
return (
<React.Fragment>
{this.props.item.todo}
</React.Fragment>
);
}
}
及以下是我的物品组件,我有独特的密钥:
render() {
const { items } = this.props;
return (
items.map(item=>
<React.Fragment>
<Item key={item.todo} item={item} />
</React.Fragment>
)
);
}
随着所有这些,我会得到警告!
正如其他人所说的那样,您需要将key
设置在顶部元素上,在您的情况下为Fragment
。但是我会更改关键值。我不知道您在item.todo
中拥有哪种数据,但是仅设置item.todo
值的键可能会出现问题。我会解释的。
键只能在其兄弟姐妹中
react.org文档列表和键完美地总结了这一点,因此我不会用另一种方式解释。它在下面说。
阵列中使用的键在其兄弟姐妹中应该是唯一的。但是,它们不需要在全球范围内独特。产生两个不同的数组时,我们可以使用相同的键:
(注意:它不需要是有意义的数据)。
一个密钥应稳定
这意味着在呈现密钥之间不应更改,因此请勿使用 Math.random()
人们认为使用会很好。
为什么上述重要?
在您的数据中,如果两个items.todo
是相同的值,则它将破坏上述值。您的钥匙不是唯一的。这可能会导致不必要的重新订阅者的性能问题。
我建议使用具有items.todo
和地图的index
值的密钥。这样,如果您确实具有相同的items.todo
值,则添加索引将使关键唯一。考虑到这一点,我会写你的片段。
render() {
const { items } = this.props;
return (
items.map((item, index) => (
<React.Fragment key={item.todo + index}>
<Item item={item} />
</React.Fragment>
))
);
}
这是列表和键上的react.org文档的链接,是ereact.org文档有关片段的链接。两者都提供示例和有用的信息。他们是一本很好的阅读,我强烈建议您。
我还注意到您正在使用React.Fragment
,但是只需使用Component
声明您的课程。您可以做我假设您为Component
所做的事情,并破坏Fragement
。如下:
import React, { Component, Fragment } from 'react';
因此,您的片段有点干净,如下:
items.map((item, index) => (
<Fragment key={item.todo + index}>
<Item item={item} />
<Fragment>
))
您需要按照答案中建议的@tholle建议将key
道具保留在顶部元素上。但是在这里,我想建议的是不使用<React.Fragment>
:
items.map(item=>
<Item key={item.todo} item={item} />
)
每当您不想用<div />
,<p />
等包装器包装元素时,都会使用Fragment
。由于使用<Item />
组件,使用Fragment
是不必要的。
这是您可以使用Fragment
的示例:
items.map(item=>
<React.Fragment key={item.todo}>
<Item item={item} />
<p>Another Component...</p>
</React.Fragment>
)
但是,对不起,如果您使用Fragment
的别名:<></>
不支持key
Props。它应该明确设置,根本没有道具。如果您需要使用key
:
items.map(item=>
<div key={item.todo}>
<Item item={item} />
<p>Another Component...</p>
</div>
)
这将是无效的:
items.map(item=>
<key={item.todo}>
<Item item={item} />
<p>Another Component...</p>
</>
)
您需要将key
Prop放在顶部元素上,即React.Fragment
而不是Item
。
items.map(item=>
<React.Fragment key={item.todo}>
<Item item={item} />
</React.Fragment>
)
给出react.fragment
的关键render() {
const { items } = this.props;
return (
items.map(item =>
<React.Fragment key={item.todo}>
<Item item={item} />
</React.Fragment>
)
);
}
一个更好的解决方案是使用ShortID NPM软件包。它被描述为"惊人的简短不顺序的URL友好型唯一ID生成器。"
使用阵列索引作为键是反图案。在本文中了解更多信息。ESLINT还可以防止此 ->防止在键中使用数组索引(react/no-array-index-key)
这是我的使用方式。
npm install shortid
import shortid from 'shortid'
// using https://www.npmjs.com/package/shortid to prevent duplicate fragment keys
names.map(name => {
return (
<Fragment key={`fragment-${id}-${shortid.generate()}`}>
Hello, {name}!
</Fragment>
)
});