Are your React apps not working well, especially when dealing with lists? Many programmers struggle with incorrect key assignment, resulting in ineffective visual effects.
When rendering lists poorly, your applications can feel sluggish and frustrate users, delaying their interactions. The majority of teams in the process of development are unaware that this issue can be easily rectified, resulting in an underperformance in terms of overall performance.
In this article, we will learn about dynamic key generation in React and how it can help you solve problems. With practical tips and examples, you’ll learn how to optimize your applications for better performance and user satisfaction.
Dynamic Key Generation
In an article I wrote in the past, we learn about React Keys 👀. When iterating over data with .map
, we need to give each React element a unique key
attribute so that React knows which DOM operations to trigger between renders.
In the perfect case, our data could conveniently come with unique tokens for each item, and we were able to use those tokens:
const inventory = [
{
id: 'abc123',
name: 'Soft-boiled egg press',
},
{
id: 'def456',
name: 'Hello Kitty toothbrush',
},
];
// We can use the `id` field in our iterations:
inventory.map(item => (
<ShopItem key={item.id} item={item} />
));
But what if our data doesn’t have a unique token we can use?
Well, we can generate one id using the crypto API:
crypto.randomUUID()
Here is a simple implementation:
function UserList() {
const [users, setUsers] = React.useState([]);
return (
<button
onClick={(event) => {
const userData = getUsers();
const newUser = {
...userData,
// 💡 Come up with a unique value for this sticker.
id: crypto.randomUUID(),
};
const nextUsers = [...users, newUser];
setUsers(nextUsers);
}}
>
{users.map((user) => (
<img
// Use that previously-created unique value
// for the key:
key={user.id}
src={user.src}
alt={user.alt}
/>
))}
</button>
);
}
Key gotchas
There can be an alternative to dynamically generated keys, is the index
in map, take this code as an example:
import React from 'react';
function App() {
const [invitees, setInvitees] = React.useState([
'J. Jonah Jameson',
'Mary Jane',
'Aunt May',
]);
// NOTE: This form is incomplete. It should have:
// • A <label> for each input
// • A <form> tag, with submission behaviour
//
// I'm omitting them here because they're not
// relevant to the problem at hand. Please don't
// use this markup as a template for anything real 😅
return (
<>
<h1>Invitees</h1>
<ul>
{invitees.map((item, index) => (
<li key={index}>
<input
// the `defaultValue` attribute
// allows us to initialize the input
// to a particular value, without
// binding the input to it. This
// will produce an *uncontrolled*
// input.
defaultValue={invitees[index]}
/>
<button
onClick={() => {
const nextInvitees = [...invitees];
nextInvitees.splice(index, 1);
setInvitees(nextInvitees);
}}
>
Delete
</button>
</li>
))}
</ul>
</>
);
}
export default App;
Technically, it is safe to use the array index as the key if the order stays 100% consistent. If the items never change position, there won't be any issues.
But here's the thing: it's not always obvious when the order changes. There are lots of situations that can lead to problems. Here's an incomplete list:
→ Deleting items
→ Adding new items to the start/middle of the array
→ Changing the way the items are sorted (e.g. ascending → descending)
→ Filtering the items to show/hide certain elements.
There have been times when I thought it was safe to use the array index as the key, and I turned out to be wrong. 😬
Eventually, I reached a point where I got really comfortable with this stuff, and these days, I do occasionally use the array index as the key, when I'm 100% confident that it won't cause any problems (and I'm feeling a bit lazy 😅).
But until you reach that level of comfort, I'd recommend always taking a couple of extra minutes and doing things the right way, generating a truly unique value for each element in the array. It's a bit more work upfront, but it can avoid a lot of confusion down the road.
In conclusion
Mastering dynamic key generation in React is crucial for building reliable and performant applications. We've explored how to generate unique keys properly using crypto.randomUUID()
, understood why using array indices can be problematic, and learned the best practices for handling keys in different scenarios.
Remember these key takeaways:
- Always use unique, stable identifiers for your keys when possible
- Avoid using array indices unless you're absolutely certain the list order won't change
- Leverage crypto.randomUUID() for generating unique keys when needed
🔍. Similar posts
How to Effectively Use the React useId Hook in Your Apps
16 Feb 2025
The Simple Method for Lifting State Up in React Effectively
16 Feb 2025
How to Fix Mutation Bugs in Your React Complex State Logic
10 Feb 2025