我收到了这个警告:
警告:数组或迭代器中的每个子节点都应该有一个唯一的“key”prop。检查EventsTable的render方法。有关详细信息,请参阅fb.me/react-warning-keys。
react-runtime-dev.js?8fefd85d334323f8baa58410bac59b2a7f426ea7:21998警告:数组或迭代器中的每个子节点都应该有一个唯一的“key”prop。检查Event的render方法。有关详细信息,请参阅fb.me/react-warning-keys。
这是EventsTable
:
EventsTable = React.createClass({
displayName: 'EventsTable',
render() {
console.dir(this.props.list);
return (
<table className="events-table">
<thead>
<tr>
{_.keys(this.props.list[0]).map(function (key) {
if (key !== 'attributes') {
return <th>{key}</th>;
}
})}
</tr>
</thead>
<tbody>
{this.props.list.map(function (row) {
return (
<Event key={row.WhatId} data={row} />
);
})}
</tbody>
</table>
)
}
});
这是Event
:
Event = React.createClass({
displayName: 'Event',
render() {
return (
<tr>
{_.keys(this.props.data).map((x) => {
if (x !== 'attributes')
return <td>{this.props.data[x]}</td>;
})}
</tr>
)
}
});
显然我在key
组件上有<Event />
道具。我遵循惯例,你应该在组件上包含key
,而不是HTML本身(换句话说,Event
组件中的HTML标签)。根据官方的React文档:
密钥应始终直接提供给数组中的组件,而不是数组中每个组件的容器HTML子代:
我非常困惑。为什么我会收到警告?
答案 0 :(得分:10)
每次渲染列表(使用map
)时,都会向列表元素添加唯一的key
属性(从{{1}返回的最顶层或&#34; root&#34;元素回调):
map
官方Lists and Keys文档显示了您应该如何使用列表,linked reconciliations doc告诉他们这些。
当React重新呈现一个组件时,它会运行一个diff算法,找出新列表和之前版本之间发生了什么变化。比较并不总是微不足道的,但如果每个元素中都有一个唯一的键,则可以清楚地识别出已发生变化的内容。请参阅example in the doc:
render() {
return (
<div>
{this.props.data.map( element => {
// Place the key on to the returned "root" element.
// Also, in real life this should be a separate component...
return <div key={element.id}>
<span>Id (Name): </span>
<span>{element.id} </span>
<span>({element.name})</span>
</div>;
})}
</div>
)
}
很明显,添加了一个带有键<!-- previous -->
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<!-- new -->
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
的新元素,因为我们拥有所有其他键并且没有更改。没有钥匙,这将是模糊不清的。
从现在开始很容易看出:
2014
属性您应该将Math.random()
属性放置到组件的约定更好的做法,因为当您迭代列表并想要呈现元素时,这清楚地表明您应该将该代码组织到一个单独的组件。
key
属性您从文档中引用的声明:
密钥应始终直接提供给数组中的组件,而不是数组中每个组件的容器HTML子代:
表示如果在循环中渲染组件,则应在循环中设置组件的key
属性,就像在key
组件中一样:
key
错误的方法是将其传递给自己设置EventsTable
的组件:
{this.props.list.map(function (row) {
return (
<Event key={row.WhatId} data={row} />
);
})}
这个in this article还有一个很好的例子。
答案 1 :(得分:3)
我也遇到了问题,并在完成link之后修复了它。
像:
{_data.map(function(object, i){
return <div className={"row"} key={i}>
{[ object.name ,
<b className="fosfo" key={i}> {object.city} </b> , // remove the key
object.age
]}
</div>;
})}
答案 2 :(得分:1)
我意识到这个线程已经很老了,但是我只是遇到了这个问题,这让我发疯了。当我意识到时,我最终解决了它,因为我有一个<React.Fragment>
,它也需要一个唯一的密钥。
答案 3 :(得分:0)
检查是否定义了要传递给key
的变量,因为如果它是undefined
,则错误将相同,但看起来代码应该可以工作。
答案 4 :(得分:0)
最简单的解决方法是为您要映射的项目创建一个单独的组件,并将密钥添加到该组件。
在现有组件上方创建一个新组件(或通过调用链接到它)。
const TableDataComponent = ({ k }) => {
return (
<th>{k}</th>
)
}
然后在您的代码中使用您的密钥添加该组件:
<tr>
{arr.map((k) => {
return <TableDataComponent key={k._id} k={k} />
})}
</tr>