列表渲染
大约 3 分钟
列表渲染主要是了解key的作用:key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。
key
- 一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用数据中的 id 来作为元素的 key。
- 当元素没有确定 id 的时候,万不得已你可以使用元素索引 index 作为 key。
- 如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。
- 如果你选择不指定显式的 key 值,那么 React 将默认使用索引用作为列表项目的 key 值。
查看示例代码
class组件
import React from "react";
export default class App extends React.Component {
constructor() {
super();
this.state = {
userInfo: [
{
name: "Web",
age: 20,
sex: "男",
},
{
name: "Java",
age: 22,
sex: "女",
},
{
name: "Python",
age: 20,
sex: "不男不女",
},
],
};
}
handleAdd = () => {
// push的结果返回的是数组的长度
this.setState({
userInfo: this.state.userInfo.concat([
{
name: "C#",
age: 20,
sex: "不男不女",
},
]),
});
};
render() {
return (
<div>
<div>
{this.state.userInfo.map((item, index) => {
return (
<div key={index}>
<p>姓名:{item.name}</p>
<p>年龄:{item.age}</p>
<p>性别:{item.sex}</p>
<hr />
</div>
);
})}
</div>
<button onClick={this.handleAdd}>添加数据</button>
</div>
);
}
}
hook组件
import { useState } from "react";
const App = () => {
const [userInfo, setUserInfo] = useState([
{
name: "Web",
age: 20,
sex: "男",
},
{
name: "Java",
age: 22,
sex: "女",
},
{
name: "Python",
age: 20,
sex: "不男不女",
},
]);
const handleAdd = () => {
// push的结果返回的是数组的长度
setUserInfo(
userInfo.concat([
{
name: "C#",
age: 20,
sex: "不男不女",
},
])
);
};
return (
<>
<div>
{userInfo.map((item, index) => (
<div key={index}>
<p>姓名:{item.name}</p>
<p>年龄:{item.age}</p>
<p>性别:{item.sex}</p>
<hr />
</div>
))}
</div>
<button onClick={handleAdd}>添加数据</button>
</>
);
};
export default App;
用key提取组件
元素的 key 只有放在就近的数组上下文中才有意义。
查看示例代码
错误例子
const Listitem = props => {
return <li key={props.data.id}>{props.data.title}</li>;
};
const App = () => {
const project = [
{
id: "1",
title: "Web",
},
{
id: "2",
title: "Java",
},
{
id: "3",
title: "Python",
},
];
return (
<>
{project.map(item => (
<Listitem data={item} />
))}
</>
);
};
export default App;
正确例子
const Listitem = props => {
return <li>{props.data}</li>;
};
const App = () => {
const project = [
{
id: "1",
title: "Web",
},
{
id: "2",
title: "Java",
},
{
id: "3",
title: "Python",
},
];
return (
<>
{project.map(item => (
<Listitem key={item.id} data={item.title} />
))}
</>
);
};
export default App;
key值在兄弟节点之间必须唯一
数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的 key 值:
查看示例代码
const App = () => {
const posts = [
{ id: 1, title: "Hello World", content: "Welcome to learning React!" },
{ id: 2, title: "Installation", content: "You can install React from npm." },
];
const sidebar = (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
const content = posts.map(post => (
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
));
return (
<>
{sidebar}
<hr />
{content}
</>
);
};
export default App;
通俗的讲就是:如果渲染的时候使用的是数组里面的id,那么数组里面的每一项id都必须是唯一的。两个不同组件渲染的是同一个数组,只要数组内的id唯一,那么这个是不影响的。比如:组件1渲染的key是1、2,组件2渲染的key是1、2,组件1和组件2渲染的数据源都是同一个,那么这个是不影响性能的。