
关于
应用 React 最佳实践,涵盖 Hooks、状态管理、性能优化和组件架构。
name: react-ops description: "React 开发模式、hooks、状态管理、Server Components 和性能优化。适用于:react、hooks、useState、useEffect、jsx、tsx、next.js、nextjs、app router、server components、RSC、zustand、react query、component patterns、react testing library、error boundary、suspense、react 19。" license: MIT allowed-tools: "Read Write Bash" metadata: author: claude-mods related-skills: typescript-ops, testing-ops, tailwind-ops, javascript-ops
React 操作指南
全面的 React 技能,涵盖 hooks、组件架构、状态管理、Server Components 和性能优化。
Hook 选择决策树
你要解决什么问题?
│
├─ 存储触发重新渲染的 UI 状态
│ ├─ 简单值(字符串、数字、布尔值)
│ │ └─ useState
│ ├─ 具有多个子值和逻辑的复杂状态
│ │ └─ useReducer(actions + reducer = 可预测的状态转换)
│ └─ 从现有状态派生
│ └─ 内联计算或 useMemo — 不要用 useState
│
├─ 引用一个值但不触发重新渲染
│ ├─ DOM 元素引用
│ │ └─ useRef<HTMLElement>(null) + ref={ref}
│ └─ 可变值(定时器 ID、前一个值、计数器)
│ └─ useRef(直接修改 ref.current)
│
├─ 运行副作用
│ ├─ 每次渲染后(或特定依赖)
│ │ ├─ 需要清理(订阅、定时器、中止)
│ │ │ └─ useEffect + return 清理函数
│ │ └─ 无需清理(日志、分析)
│ │ └─ useEffect + 空数组或依赖数组
│ ├─ 浏览器绘制前(DOM 操作、动画)
│ │ └─ useLayoutEffect
│ └─ 由用户操作触发(非渲染)
│ └─ 直接在事件处理器中调用 — 不要用 useEffect
│
├─ 缓存昂贵的计算
│ └─ useMemo(() => expensiveCalc(a, b), [a, b])
│
├─ 为子组件 props / 事件处理器提供稳定的回调引用
│ └─ useCallback(() => doThing(dep), [dep])
│
├─ 读取共享的 context 值
│ └─ useContext(MyContext)
│
├─ 生成稳定的唯一 ID(表单、aria)
│ └─ useId()
│
├─ 同步外部 store(Redux、Zustand 内部)
│ └─ useSyncExternalStore(subscribe, getSnapshot)
│
└─ React 19+
├─ 等待 promise 或读取 context
│ └─ use(promise | context)
├─ 表单提交状态(pending、data、action)
│ └─ useFormStatus / useActionState
└─ 服务器响应前的乐观 UI
└─ useOptimistic(state, updateFn)
组件模式决策树
你的组合挑战是什么?
│
├─ 共享隐式状态的相关组件组
│ (Tabs、Accordion、Select、Menu)
│ └─ 复合组件 + Context
│ 父组件通过 Context 提供状态
│ 子组件通过 useContext 消费
│
├─ 消费者需要控制渲染输出
│ └─ Render Props:children(props) 或 render={fn}
│ 适用于:无头 UI、灵活布局
│
├─ 对多个组件应用横切关注点(认证、日志、主题)
│ └─ 高阶组件(HOC)
│ 用 withAuth(Component) 包装
│ 纯逻辑优先使用自定义 hooks
│
├─ 封装可复用的有状态逻辑
│ └─ 自定义 Hook — 尽可能优先于 HOC
│ 可组合、可测试、无包装地狱
│
├─ 需要从父组件命令式控制(focus、scroll、reset)
│ └─ forwardRef + useImperativeHandle
│
├─ 在 DOM 层级外渲染内容(modal、tooltip、toast)
│ └─ Portal:createPortal(content, document.body)
│
├─ 接受任意 children/slots 而无需 prop drilling
│ └─ Slot 模式:通过 children 或命名 props(header、footer)
│
└─ 多态渲染(button 渲染为 <a> 或 div)
└─ as prop 模式 + TypeScript 泛型
状态管理决策树
状态存在哪里,谁拥有它?
│
├─ 只有一个组件需要
│ └─ useState 或 useReducer(本地状态)
│
├─ 几个相邻组件需要
│ └─ 提升状态到最近的共同祖先 + prop drilling
│ (2-3 层是可以的)
│
├─ 多个组件需要,很少变化
│ (主题、语言、认证用户)
│ └─ React Context API
│ 按更新频率拆分 context
│ 避免单一巨大 context
│
├─ 全局客户端状态,频繁变化
│ (购物车、UI 偏好、导航)
│ ├─ 简单/小型应用 → Zustand(最少样板代码)
│ ├─ 原子更新、React Suspense 集成 → Jotai
│ └─ 大团队、时间旅行调试、复杂逻辑 → Redux Toolkit
│
├─ 服务器状态(远程数据、缓存、同步)
│ (API 数据、数据库查询)
│ └─ TanStack Query(React Query)
│ 处理:缓存、后台重新获取、加载/错误状态
│ 不要用 useState + useEffect 处理服务器数据
│
└─ 表单状态
└─ React Hook Form + Zod 验证
(简单表单用受控输入即可)
React 19 快速参考
| 功能 | API | 用途 |
|---------|-----|---------|
| use() hook | use(promise) / use(context) | 在渲染中等待 promise,条件性读取 context |
| Actions | async function action(formData) | 带内置 pending 状态的异步转换 |
| useFormStatus | const { pending } = useFormStatus() | 表单提交状态 |
| useActionState | const [state, action] = useActionState(fn, init) | Action 结果状态 |
| useOptimistic | const [opt, setOpt] = useOptimistic(state, fn) | 乐观 UI 更新 |
兼容工具
Claude CodeCursorGitHub Copilot
标签
前端开发
