系统性盲区 — 前端 React lifecycle 审查空白¶
来源¶
v0.10.45 第二轮独立 agent 在做"是否有系统性缺失"的元-评估时发现。
内容¶
本会话累计修了 14+ 真 bug(ISSUE-0023~0029),分布:
| 主题 | 数量 |
|---|---|
| MV3 持久化 / SW 生命周期 | 5 |
| 拦截 / 调度 | 3 |
| 数据完整性(邮箱污染、writeChain) | 2 |
| UI 显示 / 文案 | 3 |
| 死代码清理 | 2 |
0 个针对:
- useEffect cleanup 缺失
- setState on unmounted component
- AbortController for in-flight fetch
- Recoil/global state 误用
- React StrictMode 双 mount race
量化扫描¶
grep -rn "useEffect\|useState" src/sections/ src/components/ | wc -l → 334 处
其中:
- 用 ahooks/useRequest 的部分 ✅ 有 unmount cancel 兜底
- 裸 useEffect(async () => { ... setState(...) }) —— 全部裸奔 ❌
- 仅 2 处用了 isMounted-style ref(都是 drag 相关,不是 fetch 保护)
为什么一直没查?¶
本会话审查模式偏 background / MV3 / 持久化。React 前端是另一套心智模型, 我的 review 路径没经过这里。
ISSUE-0029 S4 (local-data-view onMessage 无 cleanup) 是这类问题的第一个被修, 但 334 处 useEffect 中很可能还有同类。
紧迫度¶
低-中: - React 17/18 unmount race 大多数情况下表现为 console warning,不是用户可见 bug - 但长期可能导致内存泄漏 / 偶发奇怪状态 - 真要触发严重 bug 需要:快速 mount/unmount + setState race + 错误数据回流
修法(未来做)¶
Phase 1(扫描):写一个 scripts/scan-react-lifecycle.py 类似 scan:mv3:
- 扫所有 useEffect(async () => { ... }) 但无 return cleanup
- 扫所有 setState 后无 if (mounted) 守卫
- 给出基线 + diff 模式
Phase 2(系统性修):高频组件优先: - main-layout / data-view / local-data-view(已修一处) - task-view / settings-view - popup 相关组件
Phase 3(rule 化):
- 写 docs/rules/react-lifecycle-checklist.md(类比 MV3持久化陷阱清单)
- pre-commit hook 在 src/sections/ 或 src/components/ 改动时跑扫描
评估时机¶
- 用户反馈"扩展用久了切 tab 卡 / 数据更新延迟" → 立即处理
- 否则等下次 React 相关大改动时顺手做 Phase 1+2
元教训¶
审查盲区的发现需要元-评估视角。 我 4 轮自我 review + 第一轮独立 agent 都聚焦"找具体 bug",没人问"我们是不是一直没查某类风险"。 第二轮 agent 明确被 brief 这个角度才发现。
下次写 rule 时考虑加一条:"每 N 轮审查后跑一次元-评估,问:是否某类风险从未被检查过"。