Whenever you worked with rendering lists of DOM elements in React.js you have encountered this error. And most probably you solve this error in wrong way. Let me explain what's the correct approach!
import { useState } from 'react'
type USER = {
id: number,
name: string
}
const usersData: USER[] = [
{
id: 1,
name: "user 1"
},
{
id: 2,
name: "user 2"
},
{
id: 3,
name: "user 3"
},
{
id: 4,
name: "user 4"
},
{
id: 5,
name: "user 5"
}
]
function ShowUsersList() {
const [users, setUsers] = useState(usersData);
return (
users.map((user) => (
<div>
{user.name}
</div>
))
)
}
export default ShowUsersList
This is the code you wrote and got this error. The problem with this code is you haven't provided key prop to lists of divs. React needs to identify each list item uniquely. To do so it requires unique key prop.
To solve this error most people, use a quick but wrong solution to hide this error by writing code like this:
function ShowUsersList() {
const [users, setUsers] = useState(usersData);
return (
users.map((user, idx) => (
<div key={idx}>
{user.name}
</div>
))
)
}
export default ShowUsersList
But here's a catch, by doing these you will face performance issues. Especially when your list items can move (e.g. due to sorting), update, insert, or get deleted. A uniquely chosen key helps React understand exactly which item in the list get updated and make the correct updates in DOM tree more efficiently.
This also mentioned in the React's Official documentation:
Let's check practically what happens when you add item’s index in the array as its key.
In case you are deleting list items:
function ShowUsersList() {
const [users, setUsers] = useState(usersData);
const handleDelete = (id: number) => {
const filteredItems = users.filter((user) => user.id !== id);
setUsers(filteredItems);
}
return (
users.map((user, idx) => (
<div key={idx} onClick={() => handleDelete(user.id)}>
{user.name}
</div>
))
)
}
When you click any of the list items and see the change in Developer's tool Elements tab, every list item's get highlighted. Which means by deleting 0th list items only, each and all list items get re-rendered.

But when you assign consistent IDs to key prop:
function ShowUsersList() {
const [users, setUsers] = useState(usersData);
const handleDelete = (id: number) => {
const filteredItems = users.filter((user) => user.id !== id);
setUsers(filteredItems);
}
return (
users.map((user) => (
<div key={user.id} onClick={() => handleDelete(user.id)}>
{user.name}
</div>
))
)
}
Only the deleted item gets removed and nothing else get re-rendered by React.

This is happening because when you use item’s index in the array as its key, the key value for every item gets changed at run-time. And for React its completely different list of items. So, React re-renders everything.
The better way is to use unique ID which is consistent (e.g ID you will get from DB).
The correct code is:
import { useState } from 'react'
type USER = {
id: number,
name: string
}
const usersData: USER[] = [
{
id: 0, //ID from DB
name: "user 0"
},
{
id: 1,
name: "user 1"
},
{
id: 2,
name: "user 2"
},
{
id: 3,
name: "user 3"
},
{
id: 4,
name: "user 4"
}
]
function ShowUsersList() {
const [users, setUsers] = useState(usersData);
return (
users.map((user) => (
<div key={user.id}>
{user.name}
</div>
))
)
}
export default ShowUsersList
Note: Even if you didn't provide any key prop to lists of items, React will automatically use item’s index in the array as its key. Which is wrong method.
That's all about using Keys and Lists in React. I would recommend you refer React's Official Documentation to know more details about Keys in React.
You can access the source code for the code used in this explanation. You check everything on your own and really grasp this concept of React because this is really the core fundamentals of React.

Top comments (0)