Your rows in JS array should have unique key property. It'll help ReactJS to find references to the appropriate DOM nodes and update only content inside mark-up but not re-render the whole table/row.
Try removing the key={i} from the <b></b> element inside the div's (and check the console).
尝试从div的元素中删除键={i}(并检查控制台)。
In the sample, if we don't give a key to the <b> element and we want to update only the object.city, React needs to re-render the whole row vs just the element.
React documentation on the importance of keys in reconciliation: Keys
关于关键字在协调中的重要性的Reaction文档:关键字
Be careful when iterating over arrays!!
在迭代数组时要小心!!
It is a common misconception that using the index of the element in the array is an acceptable way of suppressing the error you are probably familiar with:
一种常见的误解是,使用数组中元素的索引是消除您可能熟悉的错误的一种可接受的方式:
Each child in an array should have a unique "key" prop.
However, in many cases it is not! This is anti-pattern that can in some situations lead to unwanted behavior.
然而,在许多情况下,它并不是!这是反模式,在某些情况下可能会导致不想要的行为。
Understanding the key prop
React uses the key prop to understand the component-to-DOM Element relation, which is then used for the reconciliation process. It is therefore very important that the key always remains unique, otherwise there is a good chance React will mix up the elements and mutate the incorrect one. It is also important that these keys remain static throughout all re-renders in order to maintain best performance.
That being said, one does not always need to apply the above, provided it is known that the array is completely static. However, applying best practices is encouraged whenever possible.
key is not really about performance, it's more about identity (which in turn leads to better performance). randomly assigned and changing values are not identity
We can't realistically provide keys [automatically] without knowing how your data is modeled. I would suggest maybe using some sort of hashing function if you don't have ids
We already have internal keys when we use arrays, but they are the index in the array. When you insert a new element, those keys are wrong.
This is arguably the most common mistake seen when iterating over an array in React. This approach isn't technically "wrong", it's just... "dangerous" if you don't know what you are doing. If you are iterating through a static array then this is a perfectly valid approach (e.g. an array of links in your navigation menu). However, if you are adding, removing, reordering or filtering items, then you need to be careful. Take a look at this detailed explanation in the official documentation.
In this snippet we are using a non-static array and we are not restricting ourselves to using it as a stack. This is an unsafe approach (you'll see why). Note how as we add items to the beginning of the array (basically unshift), the value for each <input> remains in place. Why? Because the key doesn't uniquely identify each item.
In other words, at first Item 1 has key={0}. When we add the second item, the top item becomes Item 2, followed by Item 1 as the second item. However, now Item 1 has key={1} and not key={0} anymore. Instead, Item 2 now has key={0}!!
As such, React thinks the <input> elements have not changed, because the Item with key 0 is always at the top!
因此,Reaction认为元素没有更改,因为键为0的项始终在顶部!
So why is this approach only sometimes bad?
那么,为什么这种方法只是有时不好呢?
This approach is only risky if the array is somehow filtered, rearranged, or items are added/removed. If it is always static, then it's perfectly safe to use. For example, a navigation menu like ["Home", "Products", "Contact us"] can safely be iterated through with this method because you'll probably never add new links or rearrange them.
In short, here's when you can safely use the index as key:
简而言之,下面是您可以安全地使用索引作为键的时候:
The array is static and will never change.
The array is never filtered (display a subset of the array).
The array is never reordered.
The array is used as a stack or LIFO (last in, first out). In other words, adding can only be done at the end of the array (i.e push), and only the last item can ever be removed (i.e pop).
Had we instead, in the snippet above, pushed the added item to the end of the array, the order for each existing item would always be correct.
While this approach will probably guarantee uniqueness of the keys, it will always force react to re-render each item in the list, even when this is not required. This a very bad solution as it greatly impacts performance. Not to mention that one cannot exclude the possibility of a key collision in the event that Math.random() produces the same number twice.
Unstable keys (like those produced by Math.random()) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.
This is arguably the best approach because it uses a property that is unique for each item in the dataset. For example, if rows contains data fetched from a database, one could use the table's Primary Key (which typically is an auto-incrementing number).
The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys
This is also a good approach. If your dataset does not contain any data that guarantees uniqueness (e.g. an array of arbitrary numbers), there is a chance of a key collision. In such cases, it is best to manually generate a unique identifier for each item in the dataset before iterating over it. Preferably when mounting the component or when the dataset is received (e.g. from props or from an async API call), in order to do this only once, and not each time the component re-renders. There are already a handful of libraries out there that can provide you such keys. Here is one example: react-key-index.
After a little trial and error (and some frustrations), adding a key property to the outermost block resolved it. Also, note that the <> tag is now replaced with the <div> tag now.
Of course, I've been naively using the iterating index (index) to populate the key value in the above example. Ideally, you'd use something which is unique to the list item.
Each child in a list should have a unique "key" prop.
if your code is complete right, but if on
如果您的代码是完全正确的,但如果
<ObjectRow key={someValue} />
someValue is undefined!!! Please check this first. You can save hours.
未定义某个值!请先把这个检查一下。你可以节省几个小时。
Here are the React docs that explain well using the Key property, the key should be defined at the parent component it should not be used inside the child component.React Docs
In ReactJS if you are rendering an array of elements you should have a unique key for each those elements. Normally those kinda situations are creating a list.
Best solution of define unique key in react: inside the map you initialized the name post then key define by key={post.id} or in my code you see i define the name item then i define key by key={item.id}:
As you can see, label 3, label 2, and label 1 ALL got re-rendered (flashing in the Elements panel).
如您所见,Label 3、Label 2和Label 1都被重新渲染(在元素面板中闪烁)。
The correct way key=uniqueId
Only the top new element flashes (gets re-rendered).
只有顶部的新元素闪烁(重新呈现)。
This is a warning, But addressing this will make Reacts rendering much FASTER,
这是一个警告,但解决此问题将使反应渲染速度更快,
This is because React needs to uniquely identify each items in the list. Lets say if the state of an element of that list changes in Reacts Virtual DOM then React needs to figure out which element got changed and where in the DOM it needs to change so that browser DOM will be in sync with the Reacts Virtual DOM.
I think when working with tables (or in similar examples), creating a unique key should be passed to the child component from the parent component for the sake of REUSABILITY.
我认为在使用表时(或在类似的示例中),出于可重用性的考虑,应该将唯一键从父组件传递给子组件。
Because if you are creating a table, that means you are passing data from the parent. If you assign key={row.name} maybe currently data has name property but if you want to use this table component somewhere else you assume that in each row of data that you have passed, you have name property.
In this case, the engineer knows what data it is sending, it knows that each row has an id property that is unique. Maybe in the different data set, the data set is stock prices and it does not have "id" property but "symbol"
this keyFunc should be passed to the child component as a prop to guarantee reusability and uniqueness.
这个keyFunc应该作为道具传递给子组件,以保证可重用性和唯一性。
I don't go with the detail explanation but the key to this answer is "key" just put the key attribute in your tag and ensure that every-time you iterate you give unique value to it
I've seen many times people rendering fragments <></> and it generates this issue. Try to change the fragments to null or a component with a unique key
我见过很多次人们渲染碎片<>,这就产生了这个问题。尝试将片段更改为空或具有唯一键的组件
If you are struggling with this error Each child in a list should have a unique "key" prop.
Solve by declaring index value to the key attribute inside the rendering element.
App.js component
import Map1 from './Map1';
const arr = [1,2,3,4,5];
const App = () => { return ( <>
<Map1 numb={arr} />
</> ) }
export default App
Map.js component
const Map1 = (props) => {
let itemTwo = props.numb; let itemlist = itemTwo.map((item,index) => <li key={index}>{item}</li>)
The "Each child in a list should have a unique "key" prop." warning happens in React when you create a list of elements without the special key attribute. Keys must be assigned to each element in a loop to give stable identity to elements in React.
This is pretty much the official word on a note made in the issue chat linked to above: keys are about identity of a member of a set and auto-generation of keys for items emerging out of an arbitrary iterator probably has performance implications within the React library.
Is there documentation explaining why not only the child nodes need a unique key, but also the children of those child nodes? I couldn't find anything about that specifically in the docs.
In the official docs, they use toString() to convert to string instead of leaving as number. Is this important to remember?
在官方文档中,他们使用toString()来转换为字符串,而不是将其保留为数字。记住这一点重要吗?
@skube, no, you can use integers as key as well. Not sure why they are converting it.
@Skube,不,也可以使用整数作为key。不知道他们为什么要改装。
@skube, yes that is perfectly acceptable. As stated in the examples above, you can use the item's index of the iterated array (and that's an integer). Even the docs state: "As a last resort, you can pass item's index in the array as a key". What happens though is that the key always ends up being a String anyway.
This was extremely helpful, thank you! I didn't even realize I had to put it in the outermost layer
这是非常有帮助的,谢谢!我甚至没有意识到我必须把它放在最外面的一层
I was doing similar groupings, but with table rows. You cannot wrap a table row in a div. Instead, wrap it in a react Fragment with a key, as demonstrated here: stackoverflow.com/a/51875412/750914
<> is a short syntax for <React.Fragment>. So if you want to add a key you can do like this: <React.Fragment key={item.id}>
<>是的简短语法。因此,如果您想要添加密钥,可以这样做:
I had the same issue using Material-UI where I was using a List (and elsewhere a Menu) and placing the child items of those components inside a Tooltip. Giving the Tooltip the "key" instead of the ListItem/MenuItem itself got rid of the warning.
Thank you, removing the empty tag (added for convenience) solved it.
谢谢,删除空标签(为了方便而添加)解决了这个问题。
literally saved!
真的得救了!
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
The key data.id can't possibly be unique among the YourComponents.
键data.id在YourComponents中不可能是唯一的。
This approach is potentially dangerous if the items are rearranged somehow. But if they remain static then this is fine.
如果以某种方式重新排列项目,这种方法可能会有危险。但如果它们保持不变,那么这是很好的。
@chris I completely agree with you because in this case index may be duplicated. Better to use dynamic values for key.
@Chris我完全同意您的观点,因为在这种情况下,索引可能会重复。最好对键使用动态值。
@chris I also agree with your comment. We should use dynamic values rather then index because there may be duplicates. To make it simple I did this. Btw thanks for your contribution (upvoted)
was looking for this same answer even I had a component like this and was frustated
我正在寻找同样的答案,即使我有一个这样的组件,并得到了成果
This is not entirely correct. Rendering will not be faster if you add the key prop. If you don't provide one, React will assign one automatically (the current index of the iteration).
@Chris in that case of array modification, will React correct the indices according to that if we did not provide keys. Anyway I thought removing extra overhead from React will make some impact on the rendering process.
again, React will basically do key={i}. So it depends on the data your array contains. For example, if you have the list ["Volvo", "Tesla"], then obviously the Volvo is identified by the key 0 and the Tesla with 1 - because that is the order they will appear in the loop. Now if you reorder the array the keys are swapped. For React, since "object" 0 is still at the top, it will rather interpret this change as a "rename", rather than a reorder. The correct keys here would need to be, in order, 1 then 0. You don't always reorder mid runtime, but when you do, it's a risk.
With every render cycle, you are calling the randomizer to assign a new key to each li, forcing them to re-render. This is highly inefficient. Rather, you should ensure that the assigned ID does not change if the list item does not change.
I may be incorrect but the key needs to be on the highest element that's iterated over, so if you're including the fragments they'd need to be changed to <React.Fragment key={index}><React.Fragment />. Sadly you can't include a key in an empty fragment. But I don't think they're necessary as there's only one parent element inside the map
我是一名优秀的程序员,十分优秀!