Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning: Each child in a list should have a unique "key" prop

Tags:

reactjs

I'm building an app using the Google Books API and I appear to be passing a unique key to each child in the list, but the error won't go away. I must be doing something wrong but I'm not sure what.

const BookList = (props) => {
    //map over all of the book items to create a new card for each one in the list
    const books = props.books.data.items.map((book) => {
        console.log(book.id);
        return (
            <div className="col col-lg-4 grid-wrapper">
                <BookCard
                    key={book.id}
                    image={book.volumeInfo.imageLinks.thumbnail}
                    title={book.volumeInfo.title}
                    author={book.volumeInfo.authors[0]}
                    description={book.volumeInfo.description}
                    previewLink={book.volumeInfo.previewLink}
                    buyLink={book.saleInfo.buyLink}
                />
            </div>
        );
    });

    return <div>{books}</div>;
};

Notice that after the return in const books I have a console.log(book.id), which will display all 10 unique id keys in the console. But when I try to pass it to the child of this component using key={book.id}, I get this error.

like image 383
Matt Brody Avatar asked Mar 14 '19 02:03

Matt Brody


People also ask

Why each child in a list should have a unique key prop?

⚠️ Warning: Each child in a list should have a unique “key” prop. This is because React uses a unique “key” prop on each child of the list to create a relationship between the component and the DOM. This is to ensure that react re-renders the child correctly next time.

When rendering arrays in JSX each element must have a unique key Why?

It is therefore very important that the key always remains unique, otherwise there is a good chance React will mix up the elements and mutate the incorrect one. It is also important that these keys remain static throughout all re-renders in order to maintain best performance.

What is the key prop in React?

React's key prop gives you the ability to control component instances. Each time React renders your components, it's calling your functions to retrieve the new React elements that it uses to update the DOM. If you return the same element types, it keeps those components/DOM nodes around, even if all the props changed.

What does props with children mean in React?

Props is simply an abbreviation for properties. In React, we utilize props to send data from one component to another (from a parent component to a child component or multiple children components). They come in handy when you want the data flow in an app to be dynamic.


2 Answers

The key needs to go on the outermost returned element. In your specific case, that means changing this:

            <div className="col col-lg-4 grid-wrapper">
                <BookCard 
                    key={book.id}

to this:

            <div className="col col-lg-4 grid-wrapper" key={book.id}>
                <BookCard 
like image 139
Joseph Sible-Reinstate Monica Avatar answered Oct 15 '22 17:10

Joseph Sible-Reinstate Monica


I was using React fragments in my map() call in their simple syntax form, and was running into the same warnings with the code below:

<>
  <h3>{employee.department}</h3>
  <TableRow
    key={employee.id}
    cellValues={["Name", "Title"]} />

  <TableRow
    key={employee.id}
    cellValues={[employee.name, employee.title]}
  />
</>

Building off the accepted answer, I realized I needed the outermost element to have the ID. I learned of an alternate syntax for React fragments that allows one to put an ID on it. The resulting code below caused the warnings to go away:

<React.Fragment key={employee.id}>
  <h3>{employee.department}</h3>
  <TableRow
    cellValues={["Name", "Title"]} />

  <TableRow
    cellValues={[employee.name, employee.title]}
  />
</React.Fragment>
like image 45
King Holly Avatar answered Oct 15 '22 17:10

King Holly