Javascript 在 React 中获取关键道具警告,即使设置了关键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32256492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting key prop warning in React, even though key is set
提问by ffxsam
Problem
问题
I'm getting this warning:
我收到此警告:
Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of EventsTable. See fb.me/react-warning-keysfor more information.
react-runtime-dev.js?8fefd85d334323f8baa58410bac59b2a7f426ea7:21998 Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of Event. See fb.me/react-warning-keysfor more information.
警告:数组或迭代器中的每个子元素都应该有一个唯一的“key”属性。检查 EventsTable 的渲染方法。有关更多信息,请参阅fb.me/react-warning-keys。
react-runtime-dev.js?8fefd85d334323f8baa58410bac59b2a7f426ea7:21998 警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。检查事件的渲染方法。有关更多信息,请参阅fb.me/react-warning-keys。
Source
来源
This is EventsTable
:
这是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>
)
}
});
This is Event
:
这是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>
)
}
});
Question
题
Clearly I've got the key
prop on the <Event />
component. And I'm following the convention that you're supposed to include key
on the component, not on the HTML itself (in other words, HTML tags within the Event
component). Per the official React docs:
显然我key
在<Event />
组件上有这个道具。我遵循您应该包含key
在组件中的约定,而不是包含在 HTML 本身(换句话说,Event
组件中的HTML 标签)中。根据官方 React 文档:
The key should always be supplied directly to the components in the array, not to the container HTML child of each component in the array:
键应始终直接提供给数组中的组件,而不是提供给数组中每个组件的容器 HTML 子项:
I'm severely confused. Why am I getting warnings?
我很困惑。为什么我会收到警告?
采纳答案by sma
Have you tried adding a key
to the <th>
tag?
您是否尝试key
在<th>
标签中添加一个?
<tr>
{_.keys(this.props.list[0]).map(function (key) {
if (key !== 'attributes') {
return <th key={key}>{key}</th>;
}
})}
</tr>
回答by totymedli
tl;dr
tl;博士
Every time you render a list (use map
), add a unique key
attribute to the list elements (the topmost or "root" element returned from map
's callback):
每次渲染列表时(使用map
),key
向列表元素(从map
的回调返回的最顶层或“根”元素)添加一个唯一属性:
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>
)
}
Explanation
解释
Understanding keys in React
理解 React 中的键
The official Lists and Keysdocumentation shows how you should work with lists and the linked reconciliations doctells the whys.
官方Lists and Keys文档显示了您应该如何使用列表,链接的对帐文档说明了原因。
Basically when React rerenders a component it runs a diff algorithm that finds out what changed between the new and the previous version of the list. Comparison is not always trivial, but if there is a unique key in each element, it can be clearly identified what has changed. See the example in the doc:
基本上,当 React 重新渲染一个组件时,它会运行一个 diff 算法来找出列表的新版本和之前版本之间发生了什么变化。比较并不总是微不足道的,但如果每个元素中都有一个唯一的键,就可以清楚地确定发生了什么变化。请参阅文档中的示例:
<!-- 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>
It is clear that a new element with the key 2014
was added, since we have all the other keys and those weren't changed. Without the keys this would be obscure.
很明显,添加了一个带有键的新元素2014
,因为我们拥有所有其他键并且没有更改。如果没有钥匙,这将是模糊的。
Selecting a proper key
选择合适的键
From now it is easy to see:
从现在开始很容易看出:
- Why it is important that the key should be unique but only between the siblingsin the list, because the comparison happens only within the given list's previous and new elements.
- The key should remain the same for the same elementbetween the previous and the new version, otherwise we would compare different elements and wouldn't be able to track change. That is why it is advised to use the id of the resource or (if it doesn't have one) some other data that is unique to the element, and why you shouldn't use things like
Math.random()
.
- 为什么键应该是唯一的但仅在列表中的兄弟之间很重要,因为比较只发生在给定列表的前一个和新元素内。
- 对于旧版本和新版本之间的相同元素,键应该保持不变,否则我们将比较不同的元素并且无法跟踪更改。这就是为什么建议使用资源的 id 或(如果它没有)元素独有的其他一些数据,以及为什么不应该使用
Math.random()
.
Placing key
attribute on components
key
在组件上放置属性
The convention that you should place the key
attribute to a component is more of a good practice, because when you iterate a list and want to render an element, that clearly indicates that you should organize that code to a separate component.
将key
属性放置到组件的约定更像是一种好的做法,因为当您迭代列表并想要呈现一个元素时,这清楚地表明您应该将该代码组织到一个单独的组件中。
Setting the key
attribute in the loop
key
在循环中设置属性
The statement you quoted from the docs:
您从文档中引用的声明:
The key should always be supplied directly to the components in the array, not to the container HTML child of each component in the array:
键应始终直接提供给数组中的组件,而不是提供给数组中每个组件的容器 HTML 子项:
Means that if you render components in a loop, then you should set the key
attribute of the component in the loop, like you did it in your EventsTable
component:
意味着如果您在循环中渲染组件,那么您应该在循环中设置key
组件的属性,就像您在EventsTable
组件中所做的那样:
{this.props.list.map(function (row) {
return (
<Event key={row.WhatId} data={row} />
);
})}
The wrong way is to pass it down to the component where it would set the key
on itself:
错误的方法是将它传递给它自己设置的组件key
:
Event = React.createClass({
displayName: 'Event',
render() {
// Don't do this!
return (
<tr key={this.props.data.WhatId}>
{_.keys(this.props.data).map((x) => {
There is another good example for this in this article.
在本文中有另一个很好的例子。
回答by Michael Aaron Wilson
I realize this thread is pretty old, but I was just having this issue and it was driving me crazy. I ended up solving it when I realized because I had a <React.Fragment>
which also needs a unique key.
我意识到这个线程已经很老了,但我只是遇到了这个问题,这让我发疯了。当我意识到时我最终解决了它,因为我有一个<React.Fragment>
也需要一个唯一键。
回答by deju
回答by hlcs
Check if variable that you pass to key
is defined, because if it's undefined
then error will be same, but it looks like code should work.
检查您传递给的变量是否key
已定义,因为如果是,undefined
则错误将相同,但看起来代码应该可以工作。