← FC Coder · HomePhase 02 · Lesson 25 · 90 min
Lesson25
Phase Two · Fantasy Builder · Matchday 25 · Demo Day 5 · Phase 2 收官

化学度 + 代码闯关
Demo Day 5 · 真发家人群

Today's 3 Jobs · 今天这三件事
  1. 01
    lib/chemistry.ts · calculateChemistry 纯函数
    55 对握手 + 单人封顶 15
  2. 02
    接到 fantasy/page.tsx · 显示化学度
    标题下方一行
  3. 03
    🌟 jsx-preview · 浏览器里改 PlayerCard 代码
    改代码即看变化
  4. 04
    🎬 Demo Day 5 · 录 30 秒发家人群
    Phase 2 仪式收官

🎬 Phase 2 收官 · 90 分钟。化学度 = 11 人握手算法(同俱乐部 +10 / 同国 +5 / 单人封顶 15) —— 纯函数第一次正经写。jsx-preview 让你浏览器里改代码实时看。Demo Day 5 录 30 秒视频发家人群 —— Phase 2 仪式收官 · 比 Phase 0/1 都大。

Concept · 第 1 个新概念

纯函数 · 同输入同输出

calculateChemistry / getErrors / 任何 Math.* —— React 心智核心。

Chalk Board · 纯 vs 不纯
export function calculateChemistry(squad: Player[]) {
// 0 React · 0 useState · 0 console.log
return { total, perPlayer };
}
纯 ✅
add(a, b) => a + b
不纯 ❌
Math.random() · console.log() · squad.push()
为什么
React 重画安全 · 易测试 · 无副作用

`calculateChemistry(squad)` 给同样阵容永远算同样结果 · 不改 squad / 不写文件 · 是纯函数

Concept · 第 2 个新概念

握手算法 · 11 人两两 = 55 对

for (i) for (j = i+1) · 不重复算同一对。

Chalk Board · 嵌套循环
for (let i = 0; i < squad.length; i++) {
for (let j = i + 1; j < squad.length; j++) {
// a 和 b 这一对 · 算 bonus
}
}
11 人
11 × 10 / 2 = 55 对
每对
同俱乐部 +10 / 同国 +5 / 都没 +0
封顶
Math.min(15, perPlayer[name] + bonus)

天花板 = 11 × 15 = 165(全队完美默契)。地板 = 0(11 个不同俱乐部不同国)。

Roster · 今天 3 个新工具

纯函数 · 握手 · jsx-preview

Step 6 全曼城化学度飙升 · Step 8 浏览器改代码 · 今天的「哇」。

  1. 01
    pure function
    纯函数 —— 同输入同输出 + 不改外部世界。
    calculateChemistry 和 getErrors 都是纯函数。React 心智核心。
  2. 02
    for (i) for (j = i+1)
    握手算法 —— 11 人两两 = 55 对 · 不重复。
    j 从 i+1 起防重复算。这是经典写法。
  3. 03
    <JSXPreview jsx={code}>
    浏览器内 mini sandbox —— 改字符串实时渲染。
    components 注入 PlayerCard · bindings 注入哈兰德等。Phase 2 唯一一次用。
Sandbox · 浏览器里 mini · 不动 Cursor

代码闯关 · 改 JSX 看预览

可用变量:haaland · foden · players · playerSample。错语法会显示错。

代码 · 改我看效果

可用变量:haalandfodenplayers(全 22 人)

预览

哈兰德

ST · 评分 91

挪威 · 曼城

✅ 已选

福登

LW · 评分 87

英国 · 曼城

提示:这个浏览器里的 mini sandbox 用 ai-elements/jsx-preview 实现 · 不动你 Cursor 里的代码。改坏不要紧 —— 错语法会显示报错 · 修回去就行。

Half 2 · 在屏幕上(集训 · 90 min)

纯函数 · 接到 fantasy · jsx-preview · 录视频 · 发

做完一步就点 ✓。Step 6 全曼城 + Step 8 jsx-preview + Step 12-14 Demo Day 三个是「哇」。

01写 calculateChemistry 纯函数
01Min

Cursor + pnpm dev + lib/ 新建 chemistry.ts

老三件套。Cursor 左树 lib/ 右键 → New File → chemistry.ts。
02Min

写 export function calculateChemistry(squad): { total, perPlayer }

import type { Player } from './types'。perPlayer = {} · for (i) for (j = i+1) 嵌套握手 · 同俱乐部 +10 / 同国 +5 / Math.min(15, ...) 封顶。最后 reduce 加总。
03Min

确认 chemistry.ts 是纯函数 · 0 个 React

无 useState / 无 useEffect / 无 console.log。给同样 squad 永远返回同样结果。
02接到 fantasy + 全曼城测试
04Min

fantasy/page.tsx · import + const chemistry = calculateChemistry(squad)

import { calculateChemistry } from '@/lib/chemistry'。组件内派生段加一行。
05Min

标题下方加 {squad.length > 0 && <p>化学度:{chemistry.total} 分 ...</p>}

amber 色一行。空阵不显示(条件渲染)。保存。刷新 /fantasy 选 5 个看到数字。
06Min

🌟 全曼城测试 · 化学度飙升

清空 · 选哈兰德 / 福登 / 罗德里 / 多库 / 阿坎吉 / 埃德森 / 贝尔纳多 / 阿克 / 格瓦迪奥尔 等 11 人 · 看化学度 100-150。
07Min

对比实验 · 全英格兰 vs 全西班牙 vs 全曼城

三种 11 人组合各算化学度。看封顶效应:11 × 15 = 165 是天花板。
03🌟 jsx-preview 改代码
08Min

下方代码闯关区:看默认渲染两张卡(哈兰德金边 + 福登)

页面里嵌的 LiveCardEditor —— 左 textarea / 右预览。这是 jsx-preview · 不动你 Cursor。
09Min

把 isSelected={true} 改 false · 看右边金边消失

实时反馈。改回 true 金边又出来。
10Min

加 <h2>我的梦之队</h2> · 看立刻出现

前面加一行 <h2>...</h2>。预览立刻更新。
11Min

故意写错(漏个 />)· 看 JSXPreviewError 显示

错误友好提示。改回去错误消失。
04🎬 Demo Day 5 录视频
12Min

🎬 录 30 秒视频 · 第 1 次(熟悉)

打开 /fantasy · 镜头对屏幕 · 说三句:1) 这是 React + TS 做的梦幻阵容板 2) 15000 人挑 11 个 3) 化学度 X 分。第 1 次大概率笑场。
13Min

🎬 录 30 秒视频 · 第 2-3 次(留最好的)

第 3 次最好。保留发家人群。
14Min

📨 发家人群 · Demo Day 5 完成

微信 / Telegram 家人群 · 视频 + 截图 + 一段文字。爸爸提前打招呼让家人多夸。
05看 25 课战利品 · 截图
15Min

Cursor 浏览整个仓库 · 看 Phase 2 战利品

25 节课 page.tsx / app/fantasy/ / lib/ 工具 / components/ 复用 / scripts/ Node 脚本。这是一个真正的 React 应用。
16Min

📸 截图战利品 · Phase 2 第十张 · 集齐

Mac Shift + Cmd + 4 框「化学度 X 分」+ Demo Day 5 视频截屏。存 2026-XX-XX-Demo-Day-5.png。
Half Time · 中场 · 讲给爸爸听

4 题 · 重点:Phase 2 全回顾

第 4 题让他自己说 Phase 2 学了什么。

01什么是「纯函数」?为什么 calculateChemistry 算?Hint ↓

同输入同输出 + 不改外部。给同样 squad 永远算同样化学度 · 不改 squad / 不写 console / 不改文件。

02为什么单人封顶 +15?Hint ↓

防止一个曼城球员被 10 个曼城队友各算 +10 → 100 爆炸。封顶让数字有意义。

03jsx-preview 让你在浏览器里改代码 —— 但没改 Cursor 文件。为什么?Hint ↓

浏览器内 mini sandbox · 关掉就没。真要存还是要在 Cursor。Phase 2 唯一一次用 · 让你感受即时反馈。

04Phase 2 你做了什么?用 1 分钟回顾。Hint ↓

组件 / props / 事件 / state / interface / 阵容 / 规则 / localStorage / 15000 人 / 化学度。这是 Phase 2 全部本质点。

Player Rating · 本课温度计

给 Demo Day 5 打个分

说真话。爸爸会看到。这也是 Phase 2 的温度计。

今天难度Difficulty
0
今天开心Fun
0
Final Whistle · 终场哨

Phase 2 收官 —— 你的应用真上家人群了。

还有 16 步没打勾。Step 6 全曼城化学度 + Step 8 jsx-preview + Step 14 发家人群三个里至少做完一个,Phase 2 就过。