admin管理员组文章数量:1296915
I am new to React but I know main concept of unique key. However, I am getting a warning.
Below I have an item ponent:
class Item extends Component {
state = {}
render() {
return (
<React.Fragment>
{this.props.item.todo}
</React.Fragment>
);
}
}
And below is my items ponent and where i have unique keys:
render() {
const { items } = this.props;
return (
items.map(item=>
<React.Fragment>
<Item key={item.todo} item={item} />
</React.Fragment>
)
);
}
With all of this I am getting warning!
I am new to React but I know main concept of unique key. However, I am getting a warning.
Below I have an item ponent:
class Item extends Component {
state = {}
render() {
return (
<React.Fragment>
{this.props.item.todo}
</React.Fragment>
);
}
}
And below is my items ponent and where i have unique keys:
render() {
const { items } = this.props;
return (
items.map(item=>
<React.Fragment>
<Item key={item.todo} item={item} />
</React.Fragment>
)
);
}
With all of this I am getting warning!
Share Improve this question edited Mar 22, 2019 at 9:35 Tholle 113k22 gold badges208 silver badges197 bronze badges asked Mar 22, 2019 at 9:30 mortezashojaeimortezashojaei 4524 silver badges11 bronze badges5 Answers
Reset to default 5As others have said you need to set the key
on the top element, in your case being Fragment
. But I would change the key value. I don't know what kind of data you have in your item.todo
but just setting the key to the value of item.todo
could be problematic. I will explain.
A key should be unique only among its siblings
The react document on lists and keys sums this up perfectly, so I won't explain in another way. It says this below.
Keys used within arrays should be unique among their siblings. However, they don’t need to be globally unique. We can use the same keys when we produce two different arrays:
(Note: it does not need to be meaningful data).
A key should be stable
This means that between renders the key should not change, so don't use Math.random()
which some people think would be good to use.
Why is the above important?
In your data, if two items.todo
are the same value then it would break the above. Your key would not be unique. Which could cause performance issues from unnecessary re-renders.
I would remend using a key with the value of the items.todo
and the index
of the map. This way if you do have the same value for items.todo
adding an index would make the key unique. With this in mind I would write your snippet.
render() {
const { items } = this.props;
return (
items.map((item, index) => (
<React.Fragment key={item.todo + index}>
<Item item={item} />
</React.Fragment>
))
);
}
Here is link to the react documentation on list and keys and is a link to the react documentation regarding fragments. Both provide examples and useful information. They are a good read and I would highly remend.
Also something I noticed is that you're using React.Fragment
but then you declare your class with just Component
. Your could do what I'm assuming you've done for Component
and destructure the Fragement
. Something like below:
import React, { Component, Fragment } from 'react';
So you're snippet is a bit more clean, like below:
items.map((item, index) => (
<Fragment key={item.todo + index}>
<Item item={item} />
<Fragment>
))
You need to keep the key
props on the top element as @Tholle suggested in the answer. But here, what I want to suggest is not to use the <React.Fragment>
:
items.map(item=>
<Item key={item.todo} item={item} />
)
The Fragment
is used whenever you don't want to wrap the elements with a wrapper like <div />
, <p />
, etc. Since you have the <Item />
ponent, using Fragment
is unnecessary.
Here's the example in case you may use the Fragment
:
items.map(item=>
<React.Fragment key={item.todo}>
<Item item={item} />
<p>Another Component...</p>
</React.Fragment>
)
But sorry if you use alias of Fragment
: the <></>
doesn't support key
props. It should be explicitly set with no props at all. You'll need to wrap them by an element if you need to use key
:
items.map(item=>
<div key={item.todo}>
<Item item={item} />
<p>Another Component...</p>
</div>
)
This will be invalid:
items.map(item=>
<key={item.todo}>
<Item item={item} />
<p>Another Component...</p>
</>
)
You need to put the key
prop on the top element, i.e. React.Fragment
instead of Item
.
items.map(item=>
<React.Fragment key={item.todo}>
<Item item={item} />
</React.Fragment>
)
give key to React.Fragment
render() {
const { items } = this.props;
return (
items.map(item =>
<React.Fragment key={item.todo}>
<Item item={item} />
</React.Fragment>
)
);
}
A better solution is to use shortid npm package. It is described as 'Amazingly short non-sequential url-friendly unique id generator.'
Using the array index as a key is an anti-pattern. Read more on this article. ESLINT also prevents this -> Prevent usage of Array index in keys (react/no-array-index-key)
Here is how I used it.
npm install shortid
import shortid from 'shortid'
// using https://www.npmjs./package/shortid to prevent duplicate fragment keys
names.map(name => {
return (
<Fragment key={`fragment-${id}-${shortid.generate()}`}>
Hello, {name}!
</Fragment>
)
});
本文标签: javascriptI am getting a unique key prop warning when i have a unique keyStack Overflow
版权声明:本文标题:javascript - I am getting a unique key prop warning when i have a unique key - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741643756a2390068.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论