Skip to content

ReactJS - Keys

Keys are special string attributes you need to include when creating lists of elements in React. Keys help React identify which items have changed, are added, or are removed. Giving elements a stable key is crucial for efficient updates and maintaining component state when lists are manipulated.

  • Efficient Updates: Keys allow React to perform a more efficient diffing algorithm. When a list reorders, without keys, React might re-render every item. With keys, React can reorder DOM elements without re-rendering them unnecessarily.
  • Preserving State: If you render a list of components, keys help preserve the internal state of those components (like input values or whether a checkbox is ticked) when items are reordered, added, or removed.

The most common use case for keys is when rendering a list of items using the map() function. Each list item returned from map() should have a unique key prop.

  • Unique Among Siblings: Keys only need to be unique among their sibling elements in the list, not globally unique.
  • Stable and Predictable: Keys should be stable. Avoid using values that might change over time, like Math.random(). If the key changes, React will treat the element as a new one and destroy the old instance, creating a new one (losing state).
  • Use Data IDs: The best keys are usually unique IDs from your data (e.g., a database ID).
  • Index as Last Resort: Using the array index as a key (key={index}) is generally discouraged if the order of items may change, or if items can be inserted/deleted from the middle of the list. This can lead to issues with component state and performance. However, it can be acceptable if the list is static and items are never reordered.

Let’s create a simple list of items. We’ll use the item’s id as the key.

import React from 'react';
function ListItem({ item }) {
return (
<li>
ID: {item.id} - Name: {item.name}
</li>
);
}
function MyListComponent() {
const items = [
{ id: 'a', name: 'Apple' },
{ id: 'b', name: 'Banana' },
{ id: 'c', name: 'Cherry' }
];
return (
<ul>
{items.map(item => (
<ListItem key={item.id} item={item} />
))}
</ul>
);
}
export default MyListComponent;

In this example, item.id is a good key because it’s unique and stable for each item. If we were to add a new item, remove one, or reorder them, React would use these keys to efficiently update the DOM and preserve the state of any ListItem components (if they had internal state).

Example demonstrating index as a key (with caveats):

Section titled “App.jsx (Illustrative, not always recommended)”
import React, { useState } from 'react';
function Content({ componentData }) {
return (
<div>
<div>{componentData.component}</div>
<div>ID from data: {componentData.id}</div>
</div>
);
}
function App() {
const [data, setData] = useState([
{ component: 'First item...', id: 1 },
{ component: 'Second item...', id: 2 },
{ component: 'Third item...', id: 3 },
]);
// Example of adding an item to the beginning, which highlights issues with index keys if items have state
const addItemToBeginning = () => {
const newItem = { component: 'New First item...', id: Date.now() }; // Unique ID
setData([newItem, ...data]);
};
return (
<div>
<button onClick={addItemToBeginning}>Add to Beginning</button>
<div>
{data.map((dynamicComponent, index) => (
<Content
key={index} // Using index as key here
componentData={dynamicComponent}
/>
))}
</div>
<p style={{marginTop: '10px', fontSize: '0.9em', color: 'gray'}}>
Note: Using 'index' as a key (as in this specific map) can be problematic if list items have internal state and the list is re-ordered or items are inserted/deleted not at the end. Prefer stable, unique IDs from your data for keys (e.g., `key={dynamicComponent.id}`).
</p>
</div>
);
}
export default App;

To render this App component, your main.js or index.js would look like:

import React from 'react';
import ReactDOM from 'react-dom/client'; // Use react-dom/client for React 18+
import App from './App'; // Assuming App.jsx is in the same directory or adjust path
const root = ReactDOM.createRoot(document.getElementById('root')); // Or 'app' if that's your root element ID
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

If you add or remove items, or change their order, React uses these keys to keep track of each element. Using stable, unique IDs from your data (like dynamicComponent.id) as keys is the most robust approach for dynamic lists.

For further reading, consult the official React documentation on Lists and Keys: https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key