Summary: in this tutorial, you will learn about the React JSX
key prop and how to render a list of elements properly using the key prop.
Rendering a list in React
In React applications, you often need to display a list of elements or components from an array of data.
To do that, you can use the array map()
method to transform an array of data into an array of components.
For example, suppose you have an array of names:
const names = ["Anthon Pham","Alex Johnson","Bob Climo"];
Code language: JavaScript (javascript)
To render a list of <li>
JSX elements, you can use the map()
method as follows:
const App = () => {
const names = ['Anthony Pham', 'Alex Johnson', 'Bob Climo'];
const renderedNames = names.map((name) => {
return <li>{name}</li>;
});
return <ul>{renderedNames}</ul>;
};
export default App;
Code language: JavaScript (javascript)
Output:
- Anthony Pham
- Alex Johnson
- Bob Climo
In this example, the map()
method transforms each name in the names
array into an array of li
elements. When rendering an array, JSX automatically concatenates its items into a single string.
The app renders the list correctly but issues the following warning message in the console:
Warning: Each child in a list should have a unique "key" prop.
Code language: JavaScript (javascript)
The warning message says that each element in a list should have a unique “key” prop.
What are the keys
When rendering a list in React, you should always add a key prop for each element or component. Keys assign each element a unique identity.
Because keys serve as an identity of each element, they must be unique within a list. Additionally, they must not change between the renderings.
Suppose you have a list of li elements:
<ul>
<li>Anthon Pham</li>
<li>Alex Johnson</li>
<li>Bob Climo</li>
</ul>
Code language: JavaScript (javascript)
When a list item (li) changes, React needs to rerender. The easiest way to do it is to delete the whole list and rerender it again. However, this is not efficient.
To make it more efficient, React compares the previous list with the new one and rerenders only the elements that have been added, modified, or removed.
To compare the list element and update the DOM tree properly, React uses the key
prop.
Typically, the keys may come from different sources:
- Database: If the data comes from a database, you can use the primary keys of the records as the
key
props of elements because they are designed to be unique. - Locally generated data: If the data is generated locally, you can generate unique keys using the built-in
randomUUID()
method of theCrypto
interface provided by the web browser oruuid
third-party packages.
The following example shows how to use the crypto.randomUUID()
method to generate the unique keys for the name list:
const App = () => {
const names = ['Anthon Pham', 'Alex Johnson', 'Bob Climo'];
const renderedNames = names.map((name) => {
return <li key={crypto.randomUUID()}>{name}</li>;
});
return <ul>{renderedNames}</ul>;
};
export default App;
Code language: JavaScript (javascript)
When you view the app on the web browser and open the console window, you will not see the warning message anymore.
Refactoring the book app
We can refactor the Book app by rendering a list of books.
Before:
import React from 'react';
import Book from './Book';
import MasteringReact from './mastering react.svg';
import PracticalReact from './practical react.svg';
import ReactInAction from './react in action.svg';
const App = () => {
return (
<main>
<h1>Favorite Books</h1>
<div>
<Book
title="Mastering React"
author="Anthony Pham"
cover={MasteringReact}
/>
<Book
title="Practical React"
author="Alex Johnson"
cover={PracticalReact}
/>
<Book
title="React in Action"
author="Bob Climo"
cover={ReactInAction}
/>
</div>
</main>
);
};
export default App;
Code language: JavaScript (javascript)
After:
import React from 'react';
import Book from './Book';
import MasteringReact from './mastering react.svg';
import PracticalReact from './practical react.svg';
import ReactInAction from './react in action.svg';
import './style.css';
export const App = () => {
const books = [
{ title: 'Mastering React', author: 'Anthony Pham', cover: MasteringReact },
{ title: 'Practical React', author: 'Alex Johnson', cover: PracticalReact },
{ title: 'React in Action', author: 'Bob Climo', cover: ReactInAction },
];
const renderedBooks = books.map((book) => {
return (
<Book
key={crypto.randomUUID()}
title={book.title}
author={book.author}
cover={book.cover}
/>
);
});
return (
<main>
<h1>Favorite Books</h1>
<div className="book-list">{renderedBooks}</div>
</main>
);
};
Code language: JavaScript (javascript)
How it works.
First, extract book data into an array of book objects, each containing three fields title, author, and cover.
const books = [
{ title: 'Mastering React', author: 'Anthony Pham', cover: MasteringReact },
{ title: 'Practical React', author: 'Alex Johnson', cover: PracticalReact },
{ title: 'React in Action', author: 'Bob Climo', cover: ReactInAction },
];
Code language: JavaScript (javascript)
Second, transform the books
array into an array of Book
components:
const renderedBooks = books.map((book) => {
return (
<Book
key={crypto.randomUUID()}
title={book.title}
author={book.author}
cover={book.cover}
/>
);
});
Code language: JavaScript (javascript)
Third, render the Book
component list:
return (
<main>
<h1>Favorite Books</h1>
<div className="book-list">{renderedBooks}</div>
</main>
);
Code language: JavaScript (javascript)
Summary
- Use the
map()
method to transform an array of data into an array of elements in JSX. - Use the
key
props for list items when rendering a list in JSX.