# 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[]` 表示“字符串数组”,空的 `[]` 表示开始时还没有选中任何活动。下面的 `includes`、`filter` 和 `...current` 分别用于查找、移除和追加 ID;它们会生成新数组,不直接改掉旧数组。 ```tsx const [joinedIds, setJoinedIds] = useState([]); 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 toggleJoin(item.id)}> {joinedIds.includes(item.id) ? '取消想参加' : '我想参加'} ``` 在 `ListHeaderComponent` 里显示汇总: ```tsx 想参加的活动:{joinedIds.length} 个 ``` 请给按钮加上足够的间距或背景色,让它看起来可以点击。这个版本**不保存到手机存储**,重新启动应用后状态归零是预期行为;不要把它描述成真实的报名系统。 ## 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`,这个选做内容不影响基本验收。