警告:列表中的每个子项都应该有一个唯一的“key”属性。

93

我正在使用谷歌图书API构建一个应用程序,似乎我将一个唯一的键传递给列表中的每个子元素,但错误仍然存在。我肯定是做错了什么,但我不确定具体是什么。

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>;
};

注意,在const books中返回后,我有一个console.log(book.id),它将在控制台中显示所有10个唯一的id键。但是当我尝试使用key={book.id}将其传递给此组件的子代时,我会收到此错误。

注意,在const books返回之后,我使用console.log(book.id)来显示控制台中的所有10个唯一的id键。但是当我尝试使用key={book.id}将其传递给此组件的子元素时,出现了错误。
2个回答

150
< p > < code >关键字 需要放在最外层返回的元素上。在您的特定情况下,这意味着需要更改以下内容:

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

到这个:

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

4
明白了!在最外层返回的元素上放置键名有具体的原因吗? - Matt Brody
18
当 React 遍历一个数组时,它只查看直接在数组中的元素。它不会一直递归查找 key。如果这样做,它将会(1)变慢,(2)在存在嵌套数组时造成歧义。 - Joseph Sible-Reinstate Monica
4
万一有其他人也遇到这个问题:如果你定义了一个自定义组件,并且它是列表中的内容,那么关键字必须放在组件本身的props上,而不是组件返回的DOM元素上。 - Mark P Neyer
1
这对我也起作用,我在.map下面有一个父元素,它继续抱怨那个,我专注于嵌套列表几个小时,现在我两个都加载而没有错误了。 - Dave Haines
1
@Brayan https://reactjs.org/docs/lists-and-keys.html 和 https://reactjs.org/docs/reconciliation.html。 - Joseph Sible-Reinstate Monica
显示剩余3条评论

18

我在map()调用中使用React片段的简单语法形式,并且在下面的代码中遇到了相同的警告:

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

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

在接受答案的基础上,我意识到需要将最外层元素设置为ID。我发现React片段有一种替代语法,可以给其添加ID。下面是最终代码,警告信息消失了:

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

  <TableRow
    cellValues={[employee.name, employee.title]}
  />
</React.Fragment>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接