React Keys and Lists — Explained!
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 ShowUsersListThis 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 ShowUsersListBut 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.
Get Parthbhovad’s stories in your inbox
Join Medium for free to get updates from this writer.
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 ShowUsersListNote: Even if you didn’t provide any
keyprop to lists of items, React will automatically use item’s index in the array as itskey. 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.









