EmmE
EmmE

Reputation: 37

Unique key React, solution?

How to pass key in this code?

{result.map(book, key => I got stuck here. I tried several times but I can't!

          { 
             result.map(book => (
                    <div className="col-md-3 mb-5">
                        <div className="card card-body bg-light text-center h-100">
                            <img className="w-100 mb-2" src={book.volumeInfo.imageLinks !== undefined ? book.volumeInfo.imageLinks.thumbnail : ''} alt={book.title} />
                            <h3 className="text-dark card-title">{book.volumeInfo.title}</h3>
                            <h5 className="text-dark card-title">{book.volumeInfo.authors}</h5>
                            </Link>
                        </div>
                    </div>
                   ))
          }

Upvotes: 0

Views: 77

Answers (5)

Daniel Santana
Daniel Santana

Reputation: 1837

Keys are one of the most important parts of the React Virtual DOM, especially if you have editable elements - Official React Documentation

TL/DR: choose one, on this order:

  • id from your database: must be strong and unique (cannot be numeric)
  • useId (a React Hook)
  • nanoid (for older React versions)

Example with useId:

import { useId } from 'react';

(...)

 return (
   <select
     value={selectedValue}
     onChange={this.onSelectedItemChanged}
     disabled={isDisabled}
   >
    {(collection ?? []).map((items) => {
      return (
       <option value={item.value} key={useId()}>
         {item.text}
       </option>
      );
    })}
   </select>
 );

For a more detailed answer, I recommend the read of the following response to this question: StackOverflow How to create unique keys for React elements?.

Upvotes: 0

Skyyye
Skyyye

Reputation: 11

It looks like you are missing the parentheses.

If you want to use the item index as a key, you can try:

{result.map((book, index) => <div key={index} ...>...</div>)}

But, using indexes for keys is not recommended. It would be better to use IDs from your data as keys.

More info about this: Index as a key is an anti-pattern.

Upvotes: 0

krpecd
krpecd

Reputation: 43

The best way is to use unique key for the books (ID). It might be doing problems if you will delete the books for example.

I don't know your API implementation but it could look something like that:

 {result.map(book => (
    <div className="col-md-3 mb-5" key={book.id}>
        <div className="card card-body bg-light text-center h-100">
            <img className="w-100 mb-2" src={book.volumeInfo.imageLinks !== undefined ? book.volumeInfo.imageLinks.thumbnail : ''} alt={book.title} />
            <h3 className="text-dark card-title">{book.volumeInfo.title}</h3>
            <h5 className="text-dark card-title">{book.volumeInfo.authors}</h5>
            </Link>
        </div>
    </div>
))}

Upvotes: 0

Ahmed Ali
Ahmed Ali

Reputation: 169

React.Children.toArray solves this issue as it takes the job of assigning keys to children to itself. Do it like this

{React.Children.toArray(
result.map(book => (
                    <div className="col-md-3 mb-5">
                        <div className="card card-body bg-light text-center h-100">
                            <img className="w-100 mb-2" src={book.volumeInfo.imageLinks !== undefined ? book.volumeInfo.imageLinks.thumbnail : ''} alt={book.title} />
                            <h3 className="text-dark card-title">{book.volumeInfo.title}</h3>
                            <h5 className="text-dark card-title">{book.volumeInfo.authors}</h5>
                            </Link>
                        </div>
                    </div>

                )))}

Upvotes: 1

Zeno Dalla Valle
Zeno Dalla Valle

Reputation: 919

Key property must be unique in order to not break react rules. So I suggest you to use book.id if it has is property or array index with map((book,index)=>{}). Note that if you have multiple map in your code, actually in your entire app, this approach will probably fail as there’ll be more component with same key property.

So I suggest you to use a key with a prefix that prevent duplicates. For example

books.map((book, idx)=><Book key={`book_${idx}`} />)

This approach is not safe by default, so you need to be sure that no elements with the same key are generated.

Upvotes: 0

Related Questions