mcpField
R
react

react

github.com/xgent-ai开发1133 次安装1 天前更新
代码仓库

关于 react

react 是面向 React 代码编写与审查的实践指南,供开发者参考。内容涵盖 Effect 使用、渲染性能、数据获取、表单操作及 React 19 迁移,并提供审查清单。

主要功能

  1. 01Effect 使用与清理建议
  2. 02重渲染与状态管理指导
  3. 03数据获取与请求并行化
  4. 04React 19 表单与迁移要点
  5. 05性能建议及代码审查清单

适用场景

  1. 01检查组件是否不必要地使用 Effect
  2. 02审查订阅、监听器和请求清理
  3. 03优化数据获取与组件渲染
  4. 04规划 React 19 升级与表单改造

安装

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

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

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

包含的文件

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

references/
actions.md
component-patterns.md
data-fetching.md
effect-patterns.md
js-performance.md
react19-migration.md
rendering-performance.md
rerender-optimization.md

详细介绍

React 最佳实践

编写或审查 React 代码时,请遵循以下指南。

参考文件

请在同一轮中并行阅读所有相关参考资料。提供反馈时请引用它们:

  • Effect 模式:何时不需要 Effect、依赖规则、清理、订阅、useSyncExternalStore、一次性初始化
  • 重新渲染优化:memo/useMemo/useCallback、派生状态、函数式更新、延迟初始化、useDeferredValue、startTransition、useEffectEvent
  • 组件模式:Refs、useImperativeHandle、自定义 Hook 规则、受控与非受控、组合优于逐层传递 props、flushSync
  • 数据获取:并行请求、Suspense 边界、use() 和稳定的 Promise 来源、请求去重、被动监听器、localStorage 版本控制
  • 渲染性能:content-visibility、水合不匹配、资源提示、脚本加载、SVG 动画、Activity、useTransition
  • JS 性能:布局抖动、Set/Map 查找、索引映射、单次遍历、toSorted、requestIdleCallback
  • Actions:<form action>、useActionState、useFormStatus、useOptimistic——变更操作的待处理、错误和乐观状态
  • React 19 迁移:从 18 升级——根 API、findDOMNode、forwardRef、defaultProps、旧版 context、字符串 refs、propTypes、JSX 转换、TypeScript 类型、act/test-utils、StrictMode 测试次数

你可能不需要 Effect

Effect 是 React 的逃生舱口,用于与外部系统同步。如果不涉及外部系统,你可能就不需要 Effect。

Need to respond to something?
├── User interaction (click, submit, drag)?
│   └── EVENT HANDLER
├── Props/state changed and need a derived value?
│   └── CALCULATE DURING RENDER
│       └── Measurably expensive? useMemo
├── Need to reset state when an identity prop changes?
│   └── key PROP on the component
└── Component appeared on screen, and there's an external system?
    └── EFFECT, with cleanup

确实需要 Effect: 非 React 组件和浏览器 API、订阅(优先使用 useSyncExternalStore)、因组件显示而触发的分析事件、带清理逻辑的数据获取(优先使用数据库)。

不需要 Effect: 为渲染转换数据、处理用户事件、派生状态、串联状态更新、通知父组件、重置状态。

快速参考

Effects
情况不要这样做应该这样做
根据 props/state 派生状态useState + useEffect在渲染期间计算
开销较大的计算使用 useEffect 缓存使用 useMemo
在 prop 变化时重置状态useEffect + setState使用 key prop
响应用户事件使用 useEffect 监听状态使用事件处理函数
通知父组件发生变化使用 useEffect 调用 onChange在事件处理函数中调用
订阅外部存储手动使用 useEffect 订阅使用 useSyncExternalStore
获取数据使用不带清理逻辑的 useEffect使用 ignore 标记或数据库
Effect 每次渲染都会重新运行在依赖项中使用对象/函数将创建操作移到 Effect 内部
缺少依赖项eslint-disable exhaustive-deps使用函数式更新或 useEffectEvent
应用仅初始化一次使用 useRef 守卫使用模块级标志
重新渲染
  • 切勿在另一个组件内部定义组件——这会导致组件在每次渲染时重新挂载
  • 当下一个状态取决于前一个状态时,使用函数式 setState
  • 对于开销较大的默认值,使用 useState(() => expensive());普通写法会在每次渲染时运行
  • 不要用 useMemo 包装简单的布尔值或基本类型表达式
  • 拆分组合使用的 useMemo/useEffect——每个只处理一项关注点
  • 经常变化但不参与渲染的值(鼠标位置、标志)应存放在 refs 中
  • 如果启用了 React Compiler,请跳过手动使用 memo/useMemo/useCallback
数据获取
  • 对互不依赖的请求使用 Promise.all();有依赖的请求则逐项串联
  • 将 await 放到提前返回之后,并置于开销低的同步检查之后
  • 每个端点共享一个请求(SWR / React Query),而不是每个组件实例各发一个请求
  • 每个获取数据的 effect 都需要 ignore 标志或 AbortController
  • 传给 use() 的 Promise 应来自 loader、缓存、库或 Server Component,绝不能在渲染期间创建
表单和变更(React 19)
  • 优先使用 <form action={fn}>,而不是 onSubmit + preventDefault;优先使用 useActionState,而不是 loading/error reducer
  • 将预期错误作为状态从 action 返回;抛出的错误会交给错误边界
  • useFormStatus 从 react-dom 导入,且只能读取父级 <form>
  • 使用已确认的状态为 useOptimistic 提供初始值,并在 Action 中调用其 setter
  • 在 Action 内 await 之后,将状态更新再包在一个 startTransition 中
升级到 React 19
  • 先运行 npx codemod@latest react/19/migration-recipe;升级 PR 只会更改 API 表面
  • forwardRef 仍然有效——ref 是普通 prop;可择机转换
  • 函数组件上的 defaultProps 会被忽略,但类组件仍然支持
  • StrictMode 仍会让 effects 运行两次;变化在于 useMemo/useCallback 结果的复用,以及 ref 回调会被调用两次
性能
  • 优化前先测量——进行性能分析,不要凭猜测
  • 批量写入 DOM,然后只读取一次;交错操作会强制触发回流
  • 对重复查找使用 Set/Map;遍历一次,而不是链式调用 .filter().map()
  • 对 props 和 state 使用 .toSorted()——.sort() 会修改原数组
  • 使用 requestIdleCallback 延后分析和预取

Review 清单

  1. 每个 useEffect 是否都在与外部系统同步?如果没有,请提出替代方案。
  2. 依赖数组是否完整,且没有禁用 lint 检查?
  3. 每个订阅、监听器、计时器和 fetch 是否都有清理逻辑?
  4. 是否存在冗余状态——可以从其他 props 或 state 推导得出?
  5. 组件是否都定义在模块作用域?
  6. 互不依赖的异步调用是否已并行化?
  7. 是否对 props 或 state 使用了会修改原值的数组方法?
  8. 传给 use() 的每个 Promise 是否都能在多次渲染间保持稳定?
  9. 在 React 19 中:表单是否使用 Actions 并将错误作为状态返回?已移除的 API(findDOMNode、字符串 ref、旧版 context、test-utils)是否都已清除?

评论

支持 Markdown