Reputation: 36219
Is the following considered unique key in React?
<span>
{someArray.map(function (a, index) {
return (
<span key={index}>{a}</span>
);
})}
</span>
<span>
{someArray2.map(function (a, index) {
return (
<span key={index}>{a}</span>
);
})}
</span>
In this case, both imbedded span
inside the loops will have the same key, but they are children of different parents. Is this alright?
Upvotes: 12
Views: 5015
Reputation: 6968
Just chipping in after some more thinking about this. It does count as unique, because uniqueness is required only among sibling nodes.
However, one should be careful when using the array index or key: the array index does not guarantee that the order of your elements is preserved. That's because the index is not tied to the elements of the array.
As a consequence, React would do a lot more work than it should and potentially mess things up.
Bottom line is, when available use the element id, rather than the array key.
So use this:
{someArray.map(function (element) {
return (
<span key={element.id}>{element.name}</span>
);
})}
instead of this:
{someArray.map(function (element, key) {
return (
<span key={key}>{element.name}</span>
);
})}
This reasoning is explained very well here and the reconciliation algorithm docs also suggest to use a unique id:
In practice, finding a key is not really hard. Most of the time, the element you are going to display already has a unique id. When that's not the case, you can add a new ID property to your model or hash some parts of the content to generate a key.
Upvotes: 2
Reputation: 8838
Yes it does count as unique. React uses keys in its reconciler, in order to decide how to mutate the DOM in the most efficient way.
In general, the problem keys solve, is identifying nodes in the same hierarchy (sibling nodes), between renders.
For example, if you have:
// render A
<div class='parent'>
<div>one</div>
</div>
// render B
<div class='parent'>
<div>two</div>
<div>one</div>
</div>
In the second render, there is no cost-effective way of knowing that <div>one</div>
hasn't changed, and all we need to do is add a <div>two</div>
before it. If <div>one</div>
had a key, by comparing keys across renders, we could know it already existed in previous render, and all we need to do is add <div>two</div>
before.
From the react docs:
Remember that the key only has to be unique among its siblings, not globally unique
For further reading: https://facebook.github.io/react/docs/reconciliation.html#keys
Upvotes: 16