Reputation: 37
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
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:
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
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
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
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
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