← FC Coder · HomePhase 01 · Lesson 12 · 60 min
Lesson12
Phase One · First App · Matchday 12 · One Line · Ten Cards
一行渲染
10 张卡
Today's 3 Jobs · 今天这三件事
- 01扩 roster 到 10 人 · 删掉手动 3 张卡为 .map 腾位置
- 02🌟 {roster.map(name => <article>{name}</article>)}Phase 1 第一个「哇」
- 03加 className 让 10 张卡都有曼城蓝多行 JSX 用 () 包
上节课你手动写 3 个 article 渲染 3 个名字。今天 `.map` 进场 —— 一行代码,数组多长就出多少张卡。这是 Phase 1 第一个「哇」 —— Phase 0 的 `.forEach` 是兄弟(不收东西),今天的 `.map` 是会收一堆的版本。
Essence · 本质点
循环 = 对每一个做同样的事
Phase 0 第 4 课见过 .forEach;今天的 .map 是会收东西的版本。
{roster.map(name => (
<article>{name}</article>
))}
一行 · 数组多长出多少
<article>{name}</article>
))}
一行 · 数组多长出多少
Phase 0 第 4 课
cards.forEach(c => c.style...)
今天
roster.map(name => <Card .../>)
差
.forEach 不收 / .map 收一堆
JSX 里要「收一堆 JSX 卡」—— 只能用 .map。这就是为什么 React 里 .map 比 .forEach 常见 10 倍。
Essence · 多行 JSX 用 () 包
单行不用 · 多行必用
告诉浏览器「整一坨都是返回值」。
name => (
<article className="...">
<h1>{name}</h1>
</article>
)
<article className="...">
<h1>{name}</h1>
</article>
)
单行 · 不用 ()
name => <p>{name}</p>
多行 · 必用 ()
name => ( <article>...多行...</article> )
不用 ()
返回 undefined · JSX 渲染空
Roster · 今天 3 个新工具
.map · 临时变量 · () 包多行
抄着用 · 改一改数组看变化 · 5 分钟就熟。
- 01arr.map(item => <X>{item}</X>)对每一个,返回一个新东西 —— Phase 0 .forEach 的小哥哥(会返回的版本)。JSX 里渲染列表的唯一姿势。返回一个新数组 · JSX 自动铺开。
- 02name / player / x临时变量名 · 你起的 —— 数组每个元素的"临时绰号"。JSX 里跟着用同名就行 · 改一个改全部。
- 03name => (<article>多行</article>)多行 JSX 用 () 包 —— 单行不用 · 多行必用。告诉浏览器「整一坨都是返回值」。
Half 2 · 在屏幕上
回 sandbox · 一行 .map · 10 张卡出现
做完一步就点 ✓。Step 4 那一下就是今天的「哇」。
01扩 roster · 清掉手动 3 张
01Min
Cursor + pnpm dev + 打开 sandbox
回 07-my-first-card/sandbox。上节课你写了 3 个手动 article。
02Min
扩 roster 到 10 人(可分多行写)
['哈兰德','福登','罗德里','德布劳内','阿坎吉','埃德森','多库','贝尔纳多','阿克','冈萨雷斯'];保存。还是 3 张卡(因为还是手动)。
03Min
删掉 3 个手动 <article>
<main> 里只留 <p>我们队有 {roster.length} 个球员</p>。其他全删。保存 · 卡都没了。
02🌟 一行 .map · 10 张卡出来
04Min
🌟 </p> 下面加 {roster.map(name => <article>{name}</article>)}
保存 · 10 张卡(裸 article,无样式 · 一行一个名字)自动出现。Phase 1 第一个「哇」。
05Min
加 '格瓦迪奥尔' 到 roster 末尾
保存 · 第 11 张卡自动出现 · 上面计数也变 11。数据加一个 · UI 加一张 —— 这就是 .map 的真本事。
06Min
看 DevTools Console · ⚠️ key 警告
弹「Each child in a list should have a unique key prop」。今天故意不管 · 下节课对象进场时引入 key。痛点 → 解法,印象深 10 倍。
03给 .map 的 article 上 className
07Min
改成多行 · 用 () 包
{roster.map(name => (\n <article className="bg-sky-600 text-slate-50 p-6 rounded-lg mb-4">\n <h1 className="text-amber-500 text-3xl">{name}</h1>\n <p>ST · 9 号</p>\n </article>\n))}\n保存 · 10 张曼城蓝卡。
08Min
改 name → player (改临时变量名)
.map(player => ... {player} ...) · 保存 · 浏览器一样。变量名是你起的 · 改一处改全部。
09Min
发现 · 所有卡都是 ST · 9 号 假数据
现实里罗德里是 CM · 埃德森是 GK。今天不解决 · 下节课对象进场 · 每球员各自的 position。
04玩 · 加人减人 · 截图
10Min
玩 5 分钟 · 各种数组
改顺序 / 删人 / 加人 / 试 (name, index) => <p>{index + 1}. {name}</p> · 看序号自动跟着出来。
11Min
📸 截图战利品
Mac Shift + Cmd + 4 框选 10 张并排卡 · 存 2026-XX-XX-我的10张卡.png · Phase 1 第七张战利品。
Half Time · 中场 · 讲给爸爸听
4 题 · 重点:.map = 对每一个收一堆
第 3 题让他感受 .map 的真本事。
01什么是 .map?用「首发训练」的比喻讲。Hint ↓
对每一个球员收一张报告(返回一堆新东西)。.forEach 是做深蹲不收,.map 是收。
02.map 和 .forEach 差在哪?为什么 JSX 里只能用 .map?Hint ↓
.forEach 不返回,.map 返回新数组。JSX 要「收一堆 JSX」 —— 只能 .map。
03加一个名字到 roster · 浏览器自动出新卡。如果用上节课的手动写法,你要做什么?Hint ↓
手动复制一个 <article> 写 roster[10]。.map 自动 · 数据加一个 UI 加一张。
04Console 弹的黄色警告是什么?为什么今天不管?Hint ↓
key prop 缺失。下节课对象进场,每张卡有 name 当身份签,自然给 key={player.name}。
Player Rating · 本课温度计
给 Phase 1 第一个「哇」打个分
说真话。爸爸会看到。
今天难度Difficulty
0
今天开心Fun
0
Final Whistle · 终场哨
你写了一行 · 浏览器出 10 张卡。你已经是真程序员。
还有 11 步没打勾。Step 4 看到 10 张卡那一刻已经命中今天的核心 —— 其他可以下次补。