mcpField
R
react

react

github.com/danielteles开发347 次安装9 周前更新
代码仓库

关于 react

面向 React 开发与代码审查的框架技能,提供涵盖组件、Hooks、状态、数据获取、表单、服务端组件和测试的规则清单。它也指导使用 React 19、Server Components、Actions 与 React Compiler 迁移现代化代码。

主要功能

  1. 01组件与 Hooks 规则
  2. 02状态与 Effect 管理
  3. 03表单和数据获取规范
  4. 04Server Components 与 Actions
  5. 05测试及迁移检查清单

适用场景

  1. 01按规范编写 React 组件或 Hook
  2. 02审查 React 代码差异
  3. 03将旧版 React 代码现代化

安装

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

$npx skills add https://github.com/danielteles/awesome-agent-skills --skill react

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

包含的文件

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

references/
context.md
data-fetching.md
effects.md
forms.md
hooks.md
purity.md
refs.md
rendering.md
server-client.md
state.md
testing.md
worked-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 则包含完整的审查过程;运行环境允许时,可打开这些文件深入了解。


如何使用此技能

选择与任务相符的模式,并按顺序执行步骤。

模式步骤
生成 — 编写新的组件或 hook1. 保持渲染纯净;为 props 添加类型(purity)。2. 编写 useEffect 前,先检查 effects — 大多数情况并不需要它。3. 在渲染期间派生状态;使用 key 重置(state)。4. 将规则集作为检查清单逐项核对。交付前修复每一项不合规之处。
审查 — 检查拉取请求或差异1. 根据差异检查规则集。2. 对每项不合规之处,按照下方的输出格式写一条发现。3. 按顺序排列发现:先列出 must-fix,再列出 consider。4. 如果没有不合规之处,用一行说明即可。不要凭空编造发现。
迁移 — 现代化旧版 React1. 运行 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-quality Ruleset——断言渲染行为而非内部实现、包含有意义的断言,且结果确定。此组规则针对 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