Table of Contents

1、概述

在 React 中,列表组件是一个高频出现的场景。通常我们会根据一个数组中的内容,来渲染出列表组件。

例如我们有如下原始数据

code.ts
1
export const people = [{
2
id: 0,
3
name: 'Creola Katherine Johnson',
4
profession: 'mathematician',
5
accomplishment: 'spaceflight calculations',
6
imageId: 'MK3eW3A'
7
}, {
8
id: 1,
9
name: 'Mario José Molina-Pasquel Henríquez',
10
profession: 'chemist',
11
accomplishment: 'discovery of Arctic ozone hole',
12
imageId: 'mynHUSa'
13
}, {
14
id: 2,
15
name: 'Mohammad Abdus Salam',
16
profession: 'physicist',
17
accomplishment: 'electromagnetism theory',
18
imageId: 'bE7W1ji'
19
}, {
20
id: 3,
21
name: 'Percy Lavon Julian',
22
profession: 'chemist',
23
accomplishment: 'pioneering cortisone drugs, steroids and birth control pills',
24
imageId: 'IOjWm71'
25
}, {
26
id: 4,
27
name: 'Subrahmanyan Chandrasekhar',
28
profession: 'astrophysicist',
29
accomplishment: 'white dwarf star mass calculations',
30
imageId: 'lrWQx8l'
31
}];

我们要将其渲染成如下的列表

预览

2、array.map

在 React 中,我们通常会使用 array.map 来将数组中的每个元素映射成一个组件。

index.tsx
1
import { people } from './data'
2
import Avatar from './avatar'
3
4
export default function App() {
5
return (
6
<div className='space-y-4'>
7
{people.map(person => (
8
<div key={person.id} className='flex p-4 items-center gap-4 border border-gray-200 rounded-xl dark:border-0 dark:inset-ring dark:inset-ring-white/10'>
9
<Avatar person={person} size={70} />
10
<div>
11
<div className='font-bold'>{person.name}</div>
12
<div className='text-sm text-gray-500 mt-2'>{person.profession} known for {person.accomplishment}</div>
13
</div>
14
</div>
15
))}
16
</div>
17
)
18
}

这里需要解读一下为什么要用 map 来渲染列表。是因为 map 会返回一个新的数组,所以 map 之后最终得到的结果是

code.ts
1
[
2
<div key='a'>...</div>,
3
<div key='b'>...</div>,
4
<div key='c'>...</div>,
5
...
6
]

React 中支持了这种写法。可以依次渲染成组件。

INFO

需要特别注意的是,map 渲染的列表,比如给一个唯一的 key 属性。这是为了帮助 React 识别列表中的元素,从而在更新时更加快速、正确地更新和删除元素。

高阶面试题:为什么需要给列表项添加 key 属性?

高阶面试题:为什么不建议使用数字作为 key?

3、进一步封装

当我们的列表变得复杂之后,我们可以封装一个公共的列表组件。

这里比较需要重点关注的,就是我们使用 render props 的方式来传入列表项的渲染。具体的实现细节可以通过代码学习

预览
index.tsx
list.tsx
ListItem.tsx
avatar.tsx
data.ts
utils.ts
1
import List from './list'
2
import ListItem from './ListItem'
3
import { people } from './data'
4
5
export default function App() {
6
return (
7
<List list={people} listItem={
8
(person) => <ListItem key={person.id} person={person} />
9
} />
10
)
11
}
12
专栏首页
到顶
专栏目录