列表渲染
如何把数据集合转换成列表?
- 数据驱动: 用数组保存条目,再用 map 把每条数据转换为元素;箭头函数使用花括号函数体时要显式 return;
- 条件筛选: 先 filter 选出需要的条目,再 map 生成 UI,使筛选条件与展示结构分开;
function People({ people }) {
const chemists = people.filter((person) => person.job === "chemist");
return (
<ul>
{chemists.map((person) => (
<li key={person.id}>{person.name}</li>
))}
</ul>
);
}
如何为列表项选择稳定的 key?
- 身份用途: key 让 React 在插入、删除和重排后识别同一个条目,而不仅仅是消除警告;
- 唯一范围: 同一组兄弟之间必须唯一,不同数组可以复用相同 key;优先使用数据中的数据库 ID;
- 本地数据: 创建条目时生成 ID 并存入数据,不在渲染期间用随机数重新生成;
- 索引风险: 条目可能插入、删除或重排时,索引会把旧状态关联到别的数据,导致输入错位等问题;
- 特殊属性: key 由 React 使用,不会作为普通 prop 传入;子组件需要 ID 时另传
id={item.id};
一个列表项需要多个节点时如何分组?
- 显式 Fragment: 用
<Fragment key={id}>关联一组兄弟节点,同时不增加 DOM 容器;简写 Fragment 不能传 key;
import { Fragment } from "react";
function Entries({ entries }) {
return entries.map((entry) => (
<Fragment key={entry.id}>
<h2>{entry.title}</h2>
<p>{entry.body}</p>
</Fragment>
));
}
如何验证 key 是否表达了正确身份?
- 交互核对: 在列表项输入内容后执行排序、插入和删除,输入应跟随原条目而非原位置;
- 状态关联: key 对状态保留与重置的完整规则见保留与重置 state;