changan-su/forsion/react-webapp-patterns
Claude Code and agent skill by changan-su/forsion
- community
Checking that the SKILL.md file is still in the repository.
当在 Forsion Coding Space 里编写 React/前端组件、hooks、状态管理,或排查重渲染、数据获取、内存泄漏、陈旧闭包类 bug 时使用。提供 hooks 依赖数组、useEffect 竞态与清理、组件组合、状态选型(useState/Context/zustand)、数据获取三态(loading/error/取消)、列表 key、受控/非受控、memo/useMemo/useCallback 的可复制正反例(均适配 importmap+esm.sh 无构建环境)。
Install
npx vskill@latest install changan-su/forsion/react-webapp-patternsSKILL.md
Scope: written for Forsion Coding Space's static preview runtime (files served as-is, .ts/.tsx transpiled on the fly, bare imports through an importmap to esm.sh, no bundler, no npm install). In a repository that has its own build system, follow that build system instead of these rules.
React 组件与状态模式
环境=本地 dev-server 即时转译 JSX/TSX,无构建、无 npm install、无打包。裸依赖走项目根 index.html 的 importmap → https://esm.sh/<包>@<版本>,importmap 必须含 `react/jsx-runtime`(自动 JSX 运行时),CSS 用 <link> 不在 JS 里 import。 要新增包=加 importmap 条目,不装依赖。下方片段均在此环境直接可跑。本技能只讲怎么写对。
Hooks 铁律(最高频 bug 源)
- 只在组件/自定义 hook 顶层调用 hook:不能进
if/循环/回调/return之后。分支逻辑写进 hook 内部,不要用条件跳过 hook。 - 依赖数组要诚实:effect/
useMemo/useCallback读到的每个响应式值(props、state、其派生量)都必须进依赖数组。别用空数组或删依赖"消警告"——那是在造陈旧闭包。 - 陈旧闭包:effect/定时器/订阅回调会冻结创建它那一帧的变量。要读"最新值"就用函数式更新或 ref,不要把变量塞进闭包又不进依赖。
- 每个订阅/监听/定时器都要在 cleanup 里拆:
return () => {...},否则重渲染叠加、卸载后 setState 报警告、内存泄漏。
useEffect 竞态与数据获取(loading / error / 取消)
慢请求先发后到会覆盖新数据。用 AbortController + active 闩锁只认最后一次;用判别联合表达三态,别堆一堆布尔:
- 渲染端三态都要画:
loading骨架、error兜底+重试、ok内容。别只处理成功路径。 - 要缓存/重试/去重时,importmap 加
"@tanstack/react-query": "https://esm.sh/@tanstack/react-query@5?deps=react@18",别自己造。
组件组合优于继承
React 里不用类继承共享 UI,而是用 children / 具名插槽 props 拼装,用自定义 hook 抽逻辑。
- 共享行为抽成自定义 hook(
useDisclosure、useUser),共享外观抽成组件。别做"万能 props 巨型组件"。
状态管理选型(先本地,按需上升)
| 场景 | 用什么 | |
|---|---|---|
| 只在一个组件/其子树用 | useState / useReducer(多字段联动用 reducer) | |
| 少数几层传递 | 直接传 props,别急着上全局 | |
| 低频全局:主题、语言、登录用户、feature flag | Context(value 用 useMemo 包稳定) | |
| 高频全局:购物车、编辑器文档、协作光标 | zustand(切片订阅,避免全树重渲染) |
- Context value 变化会让所有消费者重渲染——高频更新别用 Context,否则要到处补 memo,那是选型错了的信号。
- zustand importmap 加
"zustand": "https://esm.sh/zustand@5?deps=react@18",用选择器只订阅需要的切片:
列表 key
- key 必须稳定且唯一——用数据 id,别用数组下标(增删/排序会错位复用 DOM,导致输入框内容串行、动画错乱)。
- 没有天然 id 就在数据源头生成一次(
crypto.randomUUID()),别在 render 里现造(每帧变=等于没 key)。
受控 vs 非受控
- 受控:
value+onChange由 state 驱动——需要校验/联动/受 state 支配时用。切忌只给value不给onChange(输入框锁死)。 - 非受控:
defaultValue+ref读取——简单表单、不需每键重渲染时更省。 - 不要混用:同一字段要么受控要么非受控;受控输入的
value不可为undefined(用?? ''兜底)。
性能:memo 家族(先别加,证明需要再加)
默认不加。多数 memo 化省不了多少,还增加复杂度和 bug 面。只在"确实避免了昂贵计算或大子树重渲染"时加,先用 React DevTools Profiler 测量,别凭感觉。
useMemo:缓存昂贵计算(大数组排序/过滤),或给下游 memo 组件提供稳定引用的对象/数组。useCallback:仅当回调传给了 `React.memo` 子组件或进了别处依赖数组时才有意义;本组件用一次的函数包了纯属浪费。React.memo:包渲染重的子组件,前提是它的 props 引用稳定——否则每次新引用照样重渲染(常见白忙)。
- 依赖里放每帧都变的值(内联对象/新数组)会让 memo 永不命中——先让依赖稳定,再谈 memo。
- 更省事的做法:把频繁变动的 state 下沉到只需要它的小组件,让父树不重渲染,常比撒 memo 更有效。
速查清单
- [ ] hooks 只在顶层调,依赖数组诚实(不删依赖消警告)
- [ ] 定时器/订阅/监听都有 cleanup;fetch 有
AbortController+active闩锁 - [ ] 数据获取 loading/error/ok 三态都渲染
- [ ] 全局 state:低频→Context,高频→zustand 切片订阅;能本地就本地
- [ ] 列表 key 用稳定 id,不用下标
- [ ] 受控输入
value配onChange且非undefined - [ ] memo 家族默认不加;加之前确认引用稳定且真省成本
- [ ] 新增包=加 importmap 条目(esm.sh),不写 npm install
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingtangu-agent/agent-skills/coding/react-webapp-patterns/SKILL.md
Popularity
- 7-day trend score
- 5
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/changan-su/forsion/react-webapp-patterns)