综合练习与 Next.js 方向
小项目清单;platform 技术栈指引。
综合练习与 Next.js 方向
这一课你将能做到
- 用 React 做一个「站点清单」:完成切换 + 保存中禁用
- 对照清单确认 props/state/列表/条件/事件都用到了
- 明确下一步进入
nextjs-essentials或补 JS 弱点
为什么要练
前面课是零件。零件不会自己变成「能点的一页」。
用一个小清单把 useState、不可变更新、map+key、条件、disabled 串起来。做完应有「我能独立写一块交互」的感觉,而不是只会背术语。
本站路径页就是「若干站点 + 状态」的放大版。练习刻意缩小,方便你抄进沙盒或临时页。
先建立图像
三项站点
├─ 切换 done(只改 state,新数组)
├─ 空列表 →「暂无站点」
└─ 「同步」假请求 500ms → 期间全禁用
跟着做
练习要求
做一个组件 StationList:
- 初始三项:
{ id, title, done } - 每项有按钮切换
done(文字「标记完成 / 未完成」即可) - 点「同步」模拟
await delay(500),期间按钮disabled,可显示「同步中」 done === true的标题加删除线或后缀 ✓- 零项时(自己清空测试)显示「暂无站点」
可选:用 Context 提供只读字符串 mode(如「准备去讲」)显示在顶部。
参考骨架(请自己补全切换与空态,不要只停留在看):
import { useState } from "react";
const INITIAL = [
{ id: "html", title: "HTML/CSS", done: false },
{ id: "js", title: "JavaScript", done: false },
{ id: "react", title: "React", done: false },
];
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export function StationList() {
const [items, setItems] = useState(INITIAL);
const [syncing, setSyncing] = useState(false);
function toggle(id) {
setItems((prev) =>
prev.map((x) => (x.id === id ? { ...x, done: !x.done } : x)),
);
}
async function sync() {
if (syncing) return;
setSyncing(true);
try {
await delay(500);
} finally {
setSyncing(false);
}
}
if (items.length === 0) return <p>暂无站点</p>;
return (
<div>
<ul>
{items.map((x) => (
<li key={x.id}>
<span style={{ textDecoration: x.done ? "line-through" : "none" }}>
{x.title}
{x.done ? " ✓" : ""}
</span>
<button
type="button"
disabled={syncing}
onClick={() => toggle(x.id)}
>
{x.done ? "标为未完成" : "标为完成"}
</button>
</li>
))}
</ul>
<button type="button" disabled={syncing} onClick={sync}>
{syncing ? "同步中" : "同步"}
</button>
</div>
);
}