React JSX Key 属性

摘要:在本教程中,您将了解 React JSX 的 key 属性,以及如何使用 key 属性正确渲染元素列表。

在 React 中渲染列表

在 React 应用程序中,您经常需要从数据数组中显示元素或组件列表。

为此,您可以使用数组 map() 方法将数据数组转换为组件数组。

例如,假设您有一个名称数组

const names = ["Anthon Pham","Alex Johnson","Bob Climo"];Code language: JavaScript (javascript)

要渲染 <li> JSX 元素列表,您可以使用 map() 方法,如下所示

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)

输出

  • Anthony Pham
  • Alex Johnson
  • Bob Climo

在此示例中,map() 方法将 names 数组中的每个名称转换为 li 元素数组。渲染数组时,JSX 会自动将其项目连接成单个字符串。

该应用程序正确渲染了列表,但在控制台中发出了以下警告消息

Warning: Each child in a list should have a unique "key" prop.Code language: JavaScript (javascript)

警告消息指出列表中的每个元素都应该有一个唯一的“key”属性。

什么是键

在 React 中渲染列表时,您应该始终为每个元素或组件添加 key 属性。键会为每个元素分配一个唯一标识

由于键作为每个元素的标识,因此它们在列表中必须是唯一的。此外,它们在渲染之间不能更改。

假设您有一个 li 元素列表

<ul>
  <li>Anthon Pham</li>
  <li>Alex Johnson</li>
  <li>Bob Climo</li>
</ul>Code language: JavaScript (javascript)

当列表项 (li) 更改时,React 需要重新渲染。最简单的方法是删除整个列表并再次重新渲染它。但是,这样做效率不高。

为了提高效率,React 会将之前的列表与新列表进行比较,并且只重新渲染已添加、修改或删除的元素。

为了正确比较列表元素并更新 DOM 树,React 使用 key 属性。

通常,键可能来自不同的来源

  • 数据库:如果数据来自数据库,您可以使用记录的 主键 作为元素的 key 属性,因为它们被设计为唯一的。
  • 本地生成的数据:如果数据是在本地生成的,您可以使用 Web 浏览器提供的 Crypto 接口的内置 randomUUID() 方法或 uuid 第三方包来生成唯一的键。

以下示例显示了如何使用 crypto.randomUUID() 方法为名称列表生成唯一的键

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)

当您在 Web 浏览器上查看应用程序并打开控制台窗口时,您将不再看到警告消息。

重构图书应用程序

我们可以通过渲染图书列表来重构 图书应用程序

之前

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)

之后

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)

它是如何工作的。

首先,将图书数据提取到图书对象的数组中,每个对象包含三个字段:标题、作者和封面。

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)

其次,将 books 数组转换为 Book 组件数组

const renderedBooks = books.map((book) => {
  return (
    <Book
      key={crypto.randomUUID()}
      title={book.title}
      author={book.author}
      cover={book.cover}
    />
  );
});Code language: JavaScript (javascript)

第三,渲染 Book 组件列表

return (
  <main>
    <h1>Favorite Books</h1>
    <div className="book-list">{renderedBooks}</div>
  </main>
);Code language: JavaScript (javascript)

摘要

  • 使用 map() 方法将数据数组转换为 JSX 中的元素数组。
  • 在 JSX 中渲染列表时,为列表项使用 key 属性。
本教程对您有帮助吗?