React 列表 & Keys
前端最常见的渲染就是"列表":菜单、评论、商品卡片,数据几乎都以数组形式存在。React 没有 v-for 这样的指令,它用数组的 map 方法把数据转换成一组 JSX 元素,key 则帮助 React 精确识别列表里的每一项。
用 map 渲染列表
遍历数组,为每个元素返回一个 JSX 节点:
const fruits = ['苹果', '香蕉', '橙子']
function FruitList() {
return (
<ul>
{fruits.map(fruit => <li key={fruit}>{fruit}</li>)}
</ul>
)
}
页面上会渲染出一个包含三种水果的无序列表。
处理对象数组
实际数据更多是对象数组,map 的箭头函数里记得用圆括号包住返回的 JSX,方便换行书写:
const users = [
{ id: 1, name: '小明' },
{ id: 2, name: '小红' }
]
function UserList() {
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
key 是什么、为什么必须有
key 是列表项的"身份证"。React 靠 key 对比新旧列表,判断哪一项被新增、删除或移动,从而只更新真正变化的那一项。缺少 key 或 key 重复,控制台会给出警告,复杂列表更新时还可能出现状态错乱。
别用数组下标当 key
用 index 当下标看似省事,但列表一旦增删或排序,下标与内容就不再对应,会引发渲染错乱(例如删除中间项后,后续项的输入框内容错位):
// 不推荐:增删、排序后索引错位
{items.map((item, index) => <li key={index}>{item}</li>)}
应该优先使用稳定且唯一的业务 id;数据确实没有 id、且列表从不增删排序时,才可退而求其次。
拆成子组件时 key 放哪里
如果用 map 渲染子组件,key 要写在子组件的标签上,而不是子组件内部的根元素上:
function UserRow({ user }) {
return <li>{user.name}</li> // 写在这里无效
}
function UserList({ users }) {
return (
<ul>
{users.map(user => (
<UserRow user={user} key={user.id} />
))}
</ul>
)
}
小结:列表渲染记住三件事——map 把数据转成 JSX、每项配一个稳定唯一的 key、key 写在被遍历元素那一层。这是 React 里最高频也最容易出错的知识点。