mcpField
R
react

react

github.com/pedronauck开发647459 次安装2 周前更新
代码仓库

关于 react

这项 React 技能为使用 React 19.2 和 React Compiler 1.0 的开发者提供指导。内容侧重适配编译器的组件与 Hook 写法,并按实现任务组织参考资料。

主要功能

  1. 01适配 React Compiler 的编码指导
  2. 02Memoization 决策建议
  3. 03纯函数与不可变性规则
  4. 04按任务组织的参考资料
  5. 05React 19 API 与测试指导

适用场景

  1. 01编写或审查组件和 Hook
  2. 02配置编译器与 lint 规则
  3. 03判断是否保留手动 memoization

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pedronauck/skills --skill react

安装后在 Claude Code 中输入/react确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
compiler-setup.md
compiler.md
components-and-types.md
effects.md
react19-apis.md
rules-of-react.md
state.md
testing.md

详细介绍

React

面向 React 19.2 和 React Compiler 1.0(babel-plugin-react-compiler),并由 eslint-plugin-react-hooks 7.1+ 检查代码。请阅读与所改动的 API 或行为对应的参考文档。只有在改动涉及相邻领域时才加载相关参考文档;复用已经阅读过的相关上下文。

编译器就是优化器

编译器会在构建时为每个组件应用相当于 memo 的优化,并缓存组件和 Hook 中的计算结果。它的粒度比手写 Hook 更细——甚至能在提前返回之后进行缓存,而这种位置在结构上不允许使用 useMemo。

代价是,React 规则不再只是风格建议,而是构建时契约。组件违反这些规则时,编译器会放弃优化:它会静默跳过该组件并继续处理。构建仍然成功,测试仍然通过,而该组件却始终没有得到优化。请编写不会让编译器放弃优化的代码。

这会带来两个与编译器出现前习惯相反的结论:

  • 对开销很小的值习惯性使用 useMemo/useCallback 现在只是噪音;而且,依赖数组不完整,比完全不缓存更糟糕——编译器无法匹配手动缓存时,就会拒绝优化该组件。
  • 违反规则只会悄然导致优化失效,而不会报错,因此 lint 规则是避免应用在不知不觉中未经优化的唯一保障。启用编译器之前,先启用这些规则。

先决定是否需要缓存

情况做法
新值或回调仅供渲染/JSX 使用直接编写;编译器会为其缓存
值作为 useEffect(或其他 Hook)的依赖数组成员,且必须保持标识不变保留 useMemo/useCallback——这是 react.dev 明确指出的逃生口
值传给未编译的使用方(原生库实例、addEventListener、未编译的包)保留手动缓存
因任何原因保留的手动缓存确保依赖项完整,否则组件会放弃优化
现有代码中正常工作的缓存保留——移除它会改变编译输出;动手之前先测试
多个组件重复执行同一个开销很大的调用编译器的缓存仅限单个组件,不会共享;将调用提升到模块级缓存或数据层
普通模块级工具函数中的开销很大的工作不会缓存;编译器只覆盖组件和 Hook
带自定义 areEqual 比较函数的 memo()保留;编译器无法实现同等功能

完成标准: 本任务新增或修改的每处缓存都能对应到上表中的某一行,且没有为了满足任何一行而添加编译器已经覆盖的 Hook。

参考文档

当你……参考文档
编写或审查任意组件或 Hook 的主体——纯函数性、变更、ref、全局变量references/rules-of-react.md
移除、保留或讨论 useMemo/useCallback/memo,或组件被编译器跳过references/compiler.md
安装或配置编译器、lint 预设,或逐步采用编译器references/compiler-setup.md
考虑使用 useEffect,或派生/同步状态references/effects.md
设计组件、组合方式、props 或 TypeScript 类型references/components-and-types.md
选择状态的存放位置,连接 context 或外部 storereferences/state.md
使用 use()、Actions、useOptimistic、<Activity>、元数据或其他 React 19 APIreferences/react19-apis.md
编写或修复组件/Hook 测试references/testing.md

应用与所改行为相关的技术规则。

Tripwires

纯度 — 渲染仅根据 props、state 和 context 计算。Math.random()、Date.now()、new Date()、crypto.randomUUID() 和 performance.now() 应放在 state 初始化器、事件处理程序或 effect 中。

变更 — props、state、hook 参数、hook 返回值,以及任何已传给 JSX 的值都是只读的;修改前先复制(setItems([...items].sort()))。在本次渲染中创建且不会逸出的值,可以随意修改。

重新赋值 — 将解构出来的 prop 视为只读:解构时重命名({ value: valueFromProps }),并派生一个新的 const。

Refs — 在 effects 和事件处理程序中读取和写入 ref.current。渲染期间唯一允许的操作是一次性延迟初始化:if (ref.current === null) ref.current = …。

全局变量 — 模块作用域用于存放常量;每次渲染的值放在 useState/useContext 中,向外部写入则放在 effect 中。在渲染期间操作计数器、数组和临时缓存,会破坏 Fast Refresh 并导致无法编译。

组件是静态的 — 在模块作用域声明组件和 hooks。在另一个组件内部定义组件(或从工厂函数返回组件),会导致每次渲染都创建新类型,从而重置 state 并卸载 DOM。

Effects — effect 用于与 React 之外的事物同步。在 effect 中同步调用 setState 来派生或复制 state,属于错误级 lint 违规;应改为在渲染期间计算。

错误 — 子组件渲染错误由 Error Boundary 捕获,绝不能用 JSX 外部的 try/catch 捕获。

Refs 是 props — 在 19 中,forwardRef 已弃用;应在 props 类型中接受 ref。同理,使用 <Context value={…}>,而不是 <Context.Provider>。

逃生舱口 — "use no memo" 是一种二分工具,需要附带书面说明和移除计划,而不是修复方案。

相关技能

TanStack Query、Router 和 Form 使用 tanstack。@xstate/store 使用 xstate-store。组件原语和 CVA 变体使用 shadcn。样式使用 tailwindcss。references/testing.md 之外的运行器配置使用 vitest。

评论

支持 Markdown