125 lines
5.8 KiB
Markdown
125 lines
5.8 KiB
Markdown
# Day_7:完成第一个可讲清楚的项目
|
||
|
||
> 最后一天的目标不是堆功能,而是让 `CampusHelper` 能演示、能说明、能从 Git 历史看出成长过程。
|
||
|
||
预计用时:60~80 分钟。
|
||
|
||
## 先回顾项目
|
||
|
||
在 Day_3 的同一个仓库中运行:
|
||
|
||
```bash
|
||
git status
|
||
git pull
|
||
npx expo start
|
||
```
|
||
|
||
依次检查:个人信息是否正确、打卡能否增加和重置、活动列表是否能滚动、4 条活动是否都有不同内容。旧功能坏了,先修复再继续。
|
||
|
||
## 1. 给活动增加“想参加”状态
|
||
|
||
这是 Day_5 的 state 和 Day_6 的列表的一次组合。因为需要记住**哪些活动**被选中,状态应放在渲染整个列表的首页组件里,而不是只放在单条文字中。
|
||
|
||
在首页导入 `useState` 与 `Pressable`,在组件开头添加:
|
||
|
||
这次状态不是一个数字,而是一组活动 ID,所以写成 `useState<string[]>([])`:尖括号里的 `string[]` 表示“字符串数组”,空的 `[]` 表示开始时还没有选中任何活动。下面的 `includes`、`filter` 和 `...current` 分别用于查找、移除和追加 ID;它们会生成新数组,不直接改掉旧数组。
|
||
|
||
```tsx
|
||
const [joinedIds, setJoinedIds] = useState<string[]>([]);
|
||
|
||
function toggleJoin(id: string) {
|
||
setJoinedIds((current) =>
|
||
current.includes(id)
|
||
? current.filter((item) => item !== id)
|
||
: [...current, id]
|
||
);
|
||
}
|
||
```
|
||
|
||
`joinedIds` 是“想参加的活动 ID”列表。点击未选中的活动时加入 ID,再点一次时移除。给 Day_6 的 `FlatList` 增加 `extraData={joinedIds}`,让列表知道选中状态变了;在 `renderItem` 的活动卡片里增加:
|
||
|
||
`FlatList` 为了性能不会只因为外部变量变化就重画每一行。`extraData` 是在告诉它:“这一列还依赖 `joinedIds`,它变化时请重新显示”。如果漏掉它,按钮可能已经改了状态,但列表上的文字或颜色没有及时更新。
|
||
|
||
```tsx
|
||
<Pressable onPress={() => toggleJoin(item.id)}>
|
||
<Text>{joinedIds.includes(item.id) ? '取消想参加' : '我想参加'}</Text>
|
||
</Pressable>
|
||
```
|
||
|
||
在 `ListHeaderComponent` 里显示汇总:
|
||
|
||
```tsx
|
||
<Text>想参加的活动:{joinedIds.length} 个</Text>
|
||
```
|
||
|
||
请给按钮加上足够的间距或背景色,让它看起来可以点击。这个版本**不保存到手机存储**,重新启动应用后状态归零是预期行为;不要把它描述成真实的报名系统。
|
||
|
||
## 2. 做一次产品检查
|
||
|
||
想象一位刚入学的同学第一次打开你的应用。选择至少 2 项改进:
|
||
|
||
- 把示例姓名、目标或活动改成与你所在学校有关的真实内容。
|
||
- 统一卡片颜色、间距和字号,让用户知道标题、说明、按钮各是什么。
|
||
- 打卡达到 3 次时显示更友好的鼓励语。
|
||
- 给“我想参加”按钮增加已选中时的颜色变化。
|
||
- 为活动补充一句简介,帮助用户判断是否感兴趣。
|
||
- 修复你自己在测试中发现的一个小问题。
|
||
|
||
每项改进都要能在手机上看到或操作。记录一个“下个版本再做”的想法,例如真正的报名、数据持久化或活动详情;把想法写进 README,不要求今天实现。
|
||
|
||
## 3. 把 README 写成项目说明书
|
||
|
||
保留 Day_3 已有 README 中有价值的内容,再补齐以下信息:
|
||
|
||
- 项目一句话介绍:面向谁,解决什么小问题。
|
||
- 当前功能:个人信息、学习打卡、校园活动、想参加标记。
|
||
- 运行方法:进入含 `package.json` 的仓库根目录,执行 `npm install`、`npx expo start`。
|
||
- 项目结构:哪个文件是首页,`components/` 和 `data/` 各负责什么。
|
||
- 已知限制与下一步:例如打卡和想参加状态在重启后归零。
|
||
- 学习总结:这四天你遇到的一个问题和解决过程。
|
||
|
||
README 的目标是让另一个新生拿到仓库后知道“怎么运行、做了什么、还没做什么”。
|
||
|
||
## 4. 用自己的操作验收
|
||
|
||
- [ ] `npm install` 后能启动,没有红色报错
|
||
- [ ] 个人信息是自己的内容
|
||
- [ ] 打卡增加、重置、条件提示正常
|
||
- [ ] 至少 4 条活动可以滚动浏览
|
||
- [ ] 每条活动的“我想参加”都能独立切换,再点可取消
|
||
- [ ] 顶部想参加数量与实际选中的活动数一致
|
||
- [ ] README 如实说明功能和限制
|
||
- [ ] `git status` 中没有 `node_modules/`、`.expo/` 等缓存
|
||
|
||
发现问题时,先写下“操作 → 预期 → 实际”,再阅读终端第一条报错。修复后重新执行相关测试。
|
||
|
||
## 5. 留下清楚的版本记录
|
||
|
||
```bash
|
||
git status
|
||
git diff
|
||
git log --oneline --graph -8
|
||
```
|
||
|
||
你应该能看到 Day_3 的 Git 练习提交,以及 Day_4 到 Day_6 对**同一个仓库**的增量提交。通过 VS Code 源代码管理面板逐个暂存今天修改的源码和 README,再用 `git diff --staged` 核对暂存内容,然后执行:
|
||
|
||
```bash
|
||
git diff --staged
|
||
git commit -m "feat: finish campus helper v1"
|
||
git push
|
||
git status
|
||
```
|
||
|
||
若提示 `nothing to commit`,先看 `git status`:可能忘了暂存,也可能没有产生新改动。不要为了凑提交而改无关文件;不要使用 `git push --force`。
|
||
|
||
## 最终提交
|
||
|
||
1. 仓库链接和首页截图。
|
||
2. 一张选中两条活动、顶部数量为 2 的截图。
|
||
3. `git log --oneline --graph -8` 截图,能看到连续的项目迭代。
|
||
4. 100~200 字总结:你最明白的一个 React Native 概念,以及下个版本想解决的问题。
|
||
|
||
## 选做:认识页面导航
|
||
|
||
如果以上内容全部完成,还有余力,可以探索默认 Expo 模板自带的页面切换:找一找 `app/` 或 `src/app/` 中的页面文件,观察它们如何对应应用中的页面。默认模板通常已经包含 [Expo Router](https://docs.expo.dev/router/introduction/);不需要为了本题再安装一套导航库。这里不要求理解路由或 `_layout.tsx`,这个选做内容不影响基本验收。
|