119 lines
4.0 KiB
Markdown
119 lines
4.0 KiB
Markdown
# Day_6:把重复内容变成数据——校园活动列表
|
||
|
||
> 昨天学会了让一个组件变化;今天学习如何用一份数据生成多个相似的界面。
|
||
|
||
预计用时:50~70 分钟。
|
||
|
||
## 今天要理解什么
|
||
|
||
- 数组保存多条活动,对象描述一条活动。
|
||
- `FlatList` 根据数据渲染列表,不需要复制粘贴多份卡片 JSX。
|
||
- 每条数据要有稳定且唯一的 `id`。
|
||
- 数据、组件和首页各有职责,项目会更容易修改。
|
||
|
||
## 1. 先确认旧功能
|
||
|
||
在 Day_4、Day_5 一直使用的仓库根目录运行:
|
||
|
||
```bash
|
||
git status
|
||
git pull
|
||
npx expo start
|
||
```
|
||
|
||
确认个人信息和打卡按钮仍可用。今天不新建项目,也不安装导航库。
|
||
|
||
## 2. 把活动写成数据
|
||
|
||
在与 `app/` 同级的位置新建 `data/activities.ts`;如果使用 `App.tsx`,就在仓库根目录建 `data/`。如果项目是 `src/app/`,则建 `src/data/`。
|
||
|
||
```ts
|
||
export type Activity = {
|
||
id: string;
|
||
title: string;
|
||
time: string;
|
||
location: string;
|
||
};
|
||
|
||
export const activities: Activity[] = [
|
||
{ id: 'club', title: '社团开放日', time: '周三 16:00', location: '活动中心' },
|
||
{ id: 'code', title: 'APP 开发分享会', time: '周五 19:00', location: '教学楼 201' },
|
||
{ id: 'run', title: '校园夜跑', time: '周六 19:30', location: '操场' },
|
||
];
|
||
```
|
||
|
||
`id` 不显示给用户,但用来区分活动。新增活动时只增加一条数据,不需要再复制一整块界面。
|
||
|
||
## 3. 在首页渲染列表
|
||
|
||
从 `react-native` 导入 `FlatList`、`Text`、`View` 和 `StyleSheet`,再从 `data/activities.ts` 导入数据。相对路径规则与 Day_4 的 `components/` 相同,只需将 `components` 改为 `data`。
|
||
|
||
参考核心写法:
|
||
|
||
```tsx
|
||
<FlatList
|
||
data={activities}
|
||
keyExtractor={(item) => item.id}
|
||
renderItem={({ item }) => (
|
||
<View style={styles.activityCard}>
|
||
<Text style={styles.activityTitle}>{item.title}</Text>
|
||
<Text>{item.time} · {item.location}</Text>
|
||
</View>
|
||
)}
|
||
ListHeaderComponent={
|
||
<View>
|
||
<Text style={styles.pageTitle}>CampusHelper</Text>
|
||
<ProfileCard name="你的姓名" major="你的专业" goal="你的目标" />
|
||
<CheckInCard />
|
||
<Text style={styles.sectionTitle}>校园活动</Text>
|
||
</View>
|
||
}
|
||
contentContainerStyle={styles.content}
|
||
/>
|
||
```
|
||
|
||
在 `StyleSheet.create` 中为 `activityCard`、`activityTitle`、`pageTitle`、`sectionTitle` 和 `content` 写样式。`content` 可以先写 `{ padding: 20, paddingBottom: 40 }`。把首页原来的外层 `ScrollView` 换成 `FlatList`,**不要把 `FlatList` 放进 `ScrollView`**;`ListHeaderComponent` 负责放置昨天已有的内容。
|
||
|
||
## 今日任务
|
||
|
||
1. 至少展示 4 条活动,其中 1 条由你自己设计。
|
||
2. 每条活动显示名称、时间、地点;`id` 不重复。
|
||
3. 只改 `activities.ts` 中的一条活动名称,观察界面是否跟着变化。
|
||
4. 个人信息和打卡功能仍然存在,列表能在小屏手机上滚动。
|
||
|
||
请用自己的话回答:如果下周要增加第五条活动,应改哪个文件?为什么不需要复制一块 JSX?
|
||
|
||
## 项目记录与提交
|
||
|
||
在 README 中增加“当前功能”列表,并写下今天的答案。提交前检查:
|
||
|
||
```bash
|
||
git status
|
||
git diff
|
||
```
|
||
|
||
逐个暂存首页、`data/activities.ts` 和 README,再提交:
|
||
|
||
```bash
|
||
git commit -m "feat: show campus activities"
|
||
git push
|
||
```
|
||
|
||
## 验收标准
|
||
|
||
- [ ] 仍在同一个 Git 仓库开发,旧功能可用
|
||
- [ ] 使用 `FlatList`,且 `keyExtractor` 返回唯一 `id`
|
||
- [ ] 至少 4 条活动,新增活动只需修改数据文件
|
||
- [ ] 没有把 `FlatList` 嵌套在同方向滚动的 `ScrollView` 中
|
||
- [ ] README 说明了当前功能,Git 历史有 Day_6 提交
|
||
|
||
提交:完整列表截图和 `git log --oneline -5` 截图。
|
||
|
||
## 遇到问题
|
||
|
||
**列表提示缺少 key:**检查每条活动是否有不同的 `id`,以及 `keyExtractor` 是否使用了它。
|
||
|
||
**活动只显示一部分:**确认外层不是固定高度的 `View`,并尝试向下滚动。
|
||
|
||
**组件导入失败:**检查 `components/`、`data/` 与 `app/` 是否按 Day_4 的规则放在同级。
|