摘要:在本教程中,您将了解 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
属性。