← FC Coder · HomePhase 02 · Lesson 18 · 60 min
Lesson18
Phase Two · Fantasy Builder · Matchday 18 · The Bell
事件 + 点击
onClick
Today's 3 Jobs · 今天这三件事
- 01PlayerCard 加 onClick={() => alert(...)}必须包箭头函数
- 02加 <button> 加入阵容 · 点弹 alert比 article 更 semantic
- 03感受 · 主动 → 被动心智反转Phase 2 第 2 个本质点
上节课卡显示完美 · 但没反应。今天 onClick 进场 —— 你点 · 卡反应。Phase 2 第 2 个本质点 · 事件驱动。从「主动跑代码」翻到「等用户点」—— 心智彻底反转。这是所有真应用的形状。
Essence · 本质点
事件驱动 · 不是你问 · 是用户告诉浏览器
按铃叫服务员 · 没按服务员不动。事件 = 用户的「按铃」。
<button onClick={() => alert('Hi')} >
点我
</button>
点我
</button>
Phase 0-17
主动 · 你写代码立刻跑
今天起
被动 · 等用户点才跑
真应用
永远是事件驱动
onClick={() => action()} 是「注册一个回调 —— 当被点时跑」。函数本身不立刻跑 · 只在事件触发时被调。
Essence · 包 vs 不包
onClick 里必须放函数 · 不是函数调用结果
onClick={alert()} ❌ · onClick={() => alert()} ✅
不包箭头 · alert 立刻跑 · onClick 收到 undefined
包箭头 · 造一个函数 · 用户点才跑
包箭头 · 造一个函数 · 用户点才跑
❌ 立刻跑
onClick={alert('Hi')}
✅ 等点才跑
onClick={() => alert('Hi')}
记法
有 () => 才是函数
Roster · 今天 3 个新工具
onClick · button · 回调里用 props
抄着用 · 看卡能反应是今天的「哇」。
- 01onClick={() => action()}按铃 —— 用户点这个 · 跑这个函数。必须包箭头函数。onClick={action()} 立刻跑 · 不等点。
- 02<button onClick={...}>Semantic 按钮 —— 自动支持键盘触发 + 读屏软件认。比 article onClick 好。Tab 聚焦 + 空格触发免费。
- 03() => alert(`选了 ${player.name}`)回调里用 props —— 函数体里能访问 player.name。22 张卡共享一个 onClick 写法 · 每张 player.name 自动正确。
Half 2 · 在屏幕上
让卡能反应 · 第一次事件驱动
做完一步就点 ✓。Step 2 那一下点卡弹 alert · 心智反转完成。
01第一个 onClick · article
01Min
Cursor + pnpm dev
打开 components/player-card/index.tsx。
02Min
<article> 加 onClick={() => alert(`你选了 ${player.name}!`)}
在 className 旁边加 onClick。保存 · sandbox 点哈兰德卡 · 弹「你选了 哈兰德!」🔔
03Min
点不同卡看不同 alert
点福登 → 你选了 福登!点罗德里 → 你选了 罗德里!22 张共享一个写法 · player.name 自动正确。
04Min
改 alert → console.log 看 DevTools Console
alert 拦截用户 · console.log 静默记录。实际程序用 console 多。改一下 · 点卡 · 看 Console 出现一行。
02升级到 <button> + 加入阵容
05Min
<article> 里加 <button onClick={...}>加入阵容</button>
<button onClick={() => alert(`${player.name} 加入阵容!`)} className="mt-2 rounded bg-amber-500 px-3 py-1 text-slate-900">加入阵容</button>。每张卡有按钮。
06Min
去掉 article 的 onClick · 只留 button
点 button 又冒泡到 article 弹两次 —— 砍 article onClick。专一 button 触发。今天不讲 stopPropagation(Phase 3)。
07Min
Tab 键聚焦 · 空格 / 回车触发
用 Tab 键移到按钮 · 空格 / 回车也弹 alert。<button> 自动支持键盘 —— <article onClick> 不支持。Semantic 在事件层的好处。
03多个 button · 各自函数
08Min
加第二个按钮 · 状态查询
<button onClick={() => alert(`${player.name} 状态查询`)}>状态</button>。放加入阵容旁边。两个按钮各自函数。
04玩 · 截图
09Min
试 onMouseOver={() => console.log(player.name)}
鼠标停在卡上自动 log · 不点击。事件还有 onMouseMove / onKeyDown / onScroll 等等 100+ · 今天只 onClick + 顺嘴试一个 onMouseOver。
10Min
📸 截图
存 2026-XX-XX-我的卡能反应.png · Phase 2 第三张战利品。
Half Time · 中场 · 讲给爸爸听
4 题 · 重点:事件驱动 · 主动 vs 被动
第 2 题让他用「包 vs 不包」的画面讲。
01什么是事件驱动?用「按铃叫服务员」的比喻讲。Hint ↓
用户主动触发 · 你不主动跑 · 等用户告诉浏览器做什么。Phase 0-17 主动 · 今天起被动。
02onClick={() => alert()} 和 onClick={alert()} 差在哪?Hint ↓
前者包箭头函数 · 等点才跑;后者立刻跑 alert · onClick 收到 undefined。
03为什么 <button> 比 <article onClick> 好?Hint ↓
Semantic + 键盘可触发 + 读屏软件认。Phase 1 #07 Semantic 在事件层的延伸。
04今天主动还是被动心智?哪种更接近真应用?Hint ↓
被动 —— 真应用永远等用户 · 用户没动就没事干。Phase 0 主动是为了破冰 · 真世界是事件驱动的。
Player Rating · 本课温度计
给「卡能反应」打个分
说真话。爸爸会看到。
今天难度Difficulty
0
今天开心Fun
0
Final Whistle · 终场哨
你的卡能反应了 —— 事件驱动登场。
还有 10 步没打勾。Step 2 第一次点卡弹 alert 那一下今天就过 —— 其他下次补。