关于 react
面向 React 开发与代码审查的框架技能,提供涵盖组件、Hooks、状态、数据获取、表单、服务端组件和测试的规则清单。它也指导使用 React 19、Server Components、Actions 与 React Compiler 迁移现代化代码。
主要功能
- 01组件与 Hooks 规则
- 02状态与 Effect 管理
- 03表单和数据获取规范
- 04Server Components 与 Actions
- 05测试及迁移检查清单
适用场景
- 01按规范编写 React 组件或 Hook
- 02审查 React 代码差异
- 03将旧版 React 代码现代化
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ danielteles/ awesome-agent-skills --skill react安装后在 Claude Code 中输入/react确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/context.mddata-fetching.mdeffects.mdforms.mdhooks.mdpurity.mdrefs.mdrendering.mdserver-client.mdstate.mdtesting.mdworked-example.md详细介绍
React 约定 — 框架技能
适用于现代 React 的 React 专属规则:函数组件、hooks、Server Components、Actions、React Compiler。它以 React 的形式给出 core-typescript 和 architecture-and-design 中一般性规则的对应规则。
基于。
core-typescript(语言规则)和architecture-and-design(设计)。只有当任务涉及某一层时,才加载对应的同级技能;如果未加载,请依据通用知识应用该层规则,不要因此阻塞工作。
此 SKILL.md 可独立使用:下方的 规则集 是完整且可执行的规则列表。每个 references/<topic>.md 都包含相应分组的理由和 ❌ / ✅ 代码示例,references/worked-example.md 则包含完整的审查过程;运行环境允许时,可打开这些文件深入了解。
如何使用此技能
选择与任务相符的模式,并按顺序执行步骤。
| 模式 | 步骤 |
|---|---|
| 生成 — 编写新的组件或 hook | 1. 保持渲染纯净;为 props 添加类型(purity)。2. 编写 useEffect 前,先检查 effects — 大多数情况并不需要它。3. 在渲染期间派生状态;使用 key 重置(state)。4. 将规则集作为检查清单逐项核对。交付前修复每一项不合规之处。 |
| 审查 — 检查拉取请求或差异 | 1. 根据差异检查规则集。2. 对每项不合规之处,按照下方的输出格式写一条发现。3. 按顺序排列发现:先列出 must-fix,再列出 consider。4. 如果没有不合规之处,用一行说明即可。不要凭空编造发现。 |
| 迁移 — 现代化旧版 React | 1. 运行 React 19 类型 codemod,然后运行 forwardRef 和 <Context.Provider> codemod。2. 启用 eslint-plugin-react-hooks(v6 或更高版本,recommended),并修复所有警告。3. 采用 React Compiler;然后删除仅用于维护引用标识的手写 useMemo / useCallback。4. 每个提交只包含一种变更。确保测试通过。 |
输出格式
每行写一条发现:
<severity> · <topic> · <file>:<line> — <what is wrong>. <the fix as an action>.
<severity>为must-fix(违反此技能中的规则或 lint 规则)或consider(安全,但规则更倾向于另一种形式)。<topic>是规则集主题的 slug(effects、state、data-fetching等)。
所有模式都必须遵守的规则
- 执行规则时,注明规则集主题。
- 优先使用当前 API,而非其前身:将
ref作为 prop,而不是使用forwardRef;使用<Context>,而不是<Context.Provider>;使用 Action,而不是手动提交的useEffect。 - 使用
useEffect前,先问问代码为什么会运行。如果答案不是“因为组件显示在屏幕上,必须与外部系统同步”,那么这段代码就不该放在 Effect 中。
规则集
purity → references/purity.md
- 渲染是纯净的:不修改 props、state 或之前渲染的值;渲染主体中没有副作用;应用树由
<StrictMode>包裹。 - 相同的 props、state 和 context 会产生相同的 JSX。
- Props 使用
type或interface定义,而不是React.FC;children 的类型为ReactNode;事件处理程序使用对应的 React 事件类型。 -
ref作为普通 prop 接收 — 新组件不使用forwardRef。 - 每个文件只包含一个组件,文件名与组件名一致;不要仅为 JSX 导入
React("jsx": "react-jsx")。 -
useId()用于提供标签 /aria-*id,绝不用于列表 key;元素选择和可访问名称遵循accessibility。 - 已启用
eslint-plugin-react和eslint-plugin-react-hooks(v6+,recommended),并修复所有警告,而不是禁用它们。
hooks → references/hooks.md
- 每个 hook 都在组件或另一个 hook 的顶层调用,并且在任何提前
return之前 — 绝不能在条件、循环、嵌套函数、事件处理程序、try/catch或传给useMemo/useReducer/useEffect的函数中调用。 - Hooks 只能在函数组件或自定义 hook 中调用。
- 共享的有状态逻辑应封装为名为
useX的自定义 hook,并返回稳定且有类型的值。 -
useEffect/useMemo/useCallback的依赖数组必须完整,且不得被抑制。
状态 → references/state.md
- 状态与使用它的组件放在一起;只有第二个组件需要相同的值时才将其提升。
- 可从 props 或其他状态推导出的值在渲染期间计算,而不是复制到状态中。
- 不将 prop 镜像到状态中;通过
key重置子树,而不是在 Effect 中清空字段。 - 绝不原地修改状态——应创建新值并设置它。
- 下一个值取决于前一个值时,使用更新函数形式(
setX(x => …))。 - 初始值计算开销较大时,使用惰性形式
useState(() => build())。 - 多个字段需要一起更改,或下一个状态取决于事件和当前状态时,使用
useReducer。 - 使用
useSyncExternalStore读取外部存储,而不是使用useState+ 订阅 Effect。
Effects → references/effects.md
- 以下情况不使用 Effect:为渲染转换数据、执行开销较大的计算(
useMemo)、在 prop 更改时重置状态(key)、响应用户事件、发送 POST 请求、串联状态更新、通知父组件或执行一次性应用初始化。 - Effect 仅用于与外部系统同步(小部件、套接字、订阅、文档标题)。
- 每个 Effect 都有清理函数,用于撤销其设置;每种同步操作使用一个 Effect。
- 获取数据的 Effect 会防止过时响应(
AbortController/ 忽略标记)——或者更好地使用缓存库(参见data-fetching)。 - 可复用的 Effect 会提取到自定义 Hook 中。
- 无需重新订阅即可读取最新值时,使用 Effect Event(
useEffectEvent),而不是不诚实的依赖数组。
refs → references/refs.md
-
useRef仅用于必须跨渲染保留且不触发渲染的值(DOM 节点、计时器 ID、前一个值)。 - 渲染期间不读取或写入
ref.current——仅在事件处理程序或 Effect 中操作。 -
ref是普通 prop;不使用forwardRef。 - 使用
useImperativeHandle暴露命令式 API,且 API 简洁并有明确名称(focus、scrollIntoView)。 - 附加监听器的
ref回调会返回清理函数,以移除监听器。 - 导航后、异步操作后以及对话框打开时,使用 ref 移动焦点。
- ref 是一种应急手段——优先尝试状态或 prop。
context → references/context.md
- Context 仅存放读取频率低、读取范围广的数据(主题、区域设置、当前用户、DI 容器)。
- 快速变化的值放在独立的 context 中,或放在带选择器的本地状态 / 存储中,而不是放在宽泛的 context 中。
- Provider 使用
<Context value={…}>(React 19),而不是<Context.Provider>。 - 使用
useContext读取 context;只有在读取必须为条件式时才使用use(Context)。 - 对 context 的
value进行记忆化处理(或启用 React Compiler)——绝不直接内联对象字面量。
数据获取 → references/data-fetching.md
- 不使用裸
useEffect获取数据:使用框架加载器、缓存库(TanStack Query、SWR),或配合由缓存创建的 promise 使用use(promise)。 - 每个请求都有一个根据其输入生成的稳定缓存键。
- 异步读取内容会用
<Suspense>包裹,并提供真实的回退内容;每个独立区域外都有错误边界。 - 渲染错误由类边界或
react-error-boundary捕获——没有对应的 Hook。 - 非紧急更新使用
useTransition/useDeferredValue。 - 突变会根据响应更新缓存;只有存在回滚路径时才使用
useOptimistic。
forms → references/forms.md
- 提交由
useActionState驱动的<form action={submitAction}>处理;子组件通过useFormStatus获取待处理状态。 - 乐观更新的行使用
useOptimistic(失败时会回滚),而不是手动实现乐观状态。 - 输入框不会在生命周期中途从受控切换为非受控,或反之;字段默认采用哪种模式,见
component-api-design、 controlled-uncontrolled。 - 校验器基于服务端使用的同一套 schema 构建,且服务端会重新校验。
- 提交失败后,已输入的值仍会保留;每个字段错误都会映射回对应字段。
server-client → references/server-client.md
- 组件默认是 Server Components(无需指令);其中不包含状态、Effects、浏览器 API 或处理器。
- 需要数据的 Server Component 是
async,并在渲染时通过await获取数据(直接读取数据库或文件)——不会为其自身数据构建客户端往返请求。 -
'use client'放在最小的交互叶子组件上,而不是页面或布局上。 - 服务端函数标记为
'use server',并作为 Action 调用;跨边界传递的 props 可序列化(除 Server Actions 外不传函数,也不传类实例)。 -
'use client'文件无法访问任何仅限服务端的模块(数据库客户端、密钥、fs);server-only会强制执行此规则。 - 数据获取发生在 Server Component 或 loader 中,结果再向下传递。
rendering → references/rendering.md
- 已启用 React Compiler;未启用时,
memo/useMemo/useCallback仅用于经 Profiler 衡量过的路径。 - 不会在渲染中创建新的对象 / 数组 / 函数并传递给 memoized 子组件。
-
key是数据中的稳定 ID,绝不使用数组索引(architecture-and-design、frontend-practices)。 - 路由使用
lazy()+<Suspense>进行代码分割;超过几百行的列表会进行虚拟化。 -
<title>/<meta>/<link rel>在负责它们的组件中渲染(React 19 会将它们提升)。 - 模态框 / 工具提示 / Toast 通过
createPortal渲染,并保留在 React 树中。
testing → references/testing.md
- 使用 React Testing Library 渲染;通过角色和可访问名称查询。
- 交互由
@testing-library/user-event驱动(需await),而非fireEvent。 - 不用模拟模块或 Hook 代替数据;边界规则(MSW)见
test-quality、test-doubles。 - 断言针对渲染结果,而非状态、props 或调用次数;异步断言使用
findBy*/waitFor。 - 通过使用自定义 Hook 的组件来测试它;仅在没有此类组件时才使用
renderHook。 - 使用
screen(整个文档范围)查询createPortal内容,而不是使用render()的返回值。 - 不使用浅渲染、Enzyme 或宽泛的快照。
- 每项测试也必须通过
test-qualityRuleset——断言渲染行为而非内部实现、包含有意义的断言,且结果确定。此组规则针对 React 机制;test-quality评判测试本身。
限制
这项技能涵盖 React 框架规则,不包括:
- 语言规则(参见
core-typescript)或与框架无关的架构(参见architecture-and-design)。 - 特定框架的路由器、加载器或元数据 API(Next.js、React Router、TanStack Start)——此处的 RSC 和数据获取规则适用,但不适用该框架自身的约定。
- 状态库(Redux Toolkit、Zustand、Jotai)——使用
architecture-and-design中的状态层级,仅在其建议使用状态库时才采用。 - 深入的无障碍内容——
useId和焦点管理会在适用之处提及;完整的审查视角见accessibility。 - React Native 和动画库。样式见
styling-and-design-tokens;i18n(react-intl策略)见i18n-and-localization;加载和交互成本见web-performance。 - 其他框架——
angular和vue是同级技能;此处的每条规则都仅适用于 React。
React Compiler 已稳定(1.0)。此处的规则假设你会采用它;若尚未采用,rendering 中有关手动记忆化的规则仍适用。
参考
这项技能与以下内容配合使用:
core-typescript— 语言基础;JSX 和 hooks 并不能让代码免于遵守它。architecture-and-design— 设计层。发生冲突时,由它决定设计,本技能决定 React API。accessibility— UI 的审查视角;React 提供的工具包括useId、基于 ref 的焦点管理和基础组件库(Radix、React Aria)。test-quality— 用于评判本技能testing组产出的单项测试。angular/vue— 同级框架技能。
评论
支持 Markdown