
About
Apply React best practices for hooks, state management, performance optimization, and component architecture.
name: react-ops description: "React development patterns, hooks, state management, Server Components, and performance optimization. Use for: 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 Operations
Comprehensive React skill covering hooks, component architecture, state management, Server Components, and performance optimization.
Hook Selection Decision Tree
What problem are you solving?
│
├─ Storing UI state that triggers re-renders
│ ├─ Simple value (string, number, boolean)
│ │ └─ useState
│ ├─ Complex state with multiple sub-values and logic
│ │ └─ useReducer (actions + reducer = predictable transitions)
│ └─ Derived from existing state
│ └─ Calculate inline or useMemo — not useState
│
├─ Referencing a value WITHOUT triggering re-render
│ ├─ DOM element reference
│ │ └─ useRef<HTMLElement>(null) + ref={ref}
│ └─ Mutable value (timer ID, previous value, counter)
│ └─ useRef (mutate ref.current directly)
│
├─ Running a side effect
│ ├─ After every render (or specific deps)
│ │ ├─ Needs cleanup (subscription, timer, abort)
│ │ │ └─ useEffect with return cleanup function
│ │ └─ No cleanup (logging, analytics)
│ │ └─ useEffect with empty or dep array
│ ├─ Before browser paint (DOM mutation, animation)
│ │ └─ useLayoutEffect
│ └─ Triggered by user action (not render)
│ └─ Call it directly in the event handler — not useEffect
│
├─ Caching an expensive computation
│ └─ useMemo(() => expensiveCalc(a, b), [a, b])
│
├─ Stable callback reference for child props / event handlers
│ └─ useCallback(() => doThing(dep), [dep])
│
├─ Reading shared context value
│ └─ useContext(MyContext)
│
├─ Generating stable unique ID (forms, aria)
│ └─ useId()
│
├─ Syncing external store (Redux, Zustand internals)
│ └─ useSyncExternalStore(subscribe, getSnapshot)
│
└─ React 19+
├─ Await a promise or read context
│ └─ use(promise | context)
├─ Form submit state (pending, data, action)
│ └─ useFormStatus / useActionState
└─ Optimistic UI before server response
└─ useOptimistic(state, updateFn)
Component Pattern Decision Tree
What's your composition challenge?
│
├─ Group of related components sharing implicit state
│ (Tabs, Accordion, Select, Menu)
│ └─ Compound Components with Context
│ Parent provides state via Context
│ Children consume via useContext
│
├─ Consumer needs to control rendering output
│ └─ Render Props: children(props) or render={fn}
│ Good for: headless UI, flexible layouts
│
├─ Apply cross-cutting concerns (auth, logging, theming)
│ to multiple components
│ └─ Higher-Order Components (HOC)
│ Wrap with withAuth(Component) or withLogging(Component)
│ Prefer custom hooks for pure logic
│
├─ Encapsulate reusable stateful logic
│ └─ Custom Hook — always prefer over HOC when possible
│ Composable, testable, no wrapper hell
│
├─ Need imperative control from parent (focus, scroll, reset)
│ └─ forwardRef + useImperativeHandle
│
├─ Render content outside DOM hierarchy (modal, tooltip, toast)
│ └─ Portal: createPortal(content, document.body)
│
├─ Accept arbitrary children/slots without prop drilling
│ └─ Slot pattern via children, or named props (header, footer)
│
└─ Polymorphic rendering (button that renders as <a> or div)
└─ as prop pattern with TypeScript generics
State Management Decision Tree
Where does this state live and who owns it?
│
├─ Only one component needs it
│ └─ useState or useReducer (local state)
│
├─ A few nearby components need it
│ └─ Lift state to nearest common ancestor + prop drilling
│ (2-3 levels is fine)
│
├─ Many components need it, rarely changes
│ (theme, locale, auth user)
│ └─ React Context API
│ Split contexts by update frequency
│ Avoid single giant context
│
├─ Global client state, changes often
│ (shopping cart, UI preferences, navigation)
│ ├─ Simple/small app → Zustand (minimal boilerplate)
│ ├─ Atomic updates, React Suspense integration → Jotai
│ └─ Large team, time-travel debugging, complex logic → Redux Toolkit
│
├─ Server state (remote data, cache, sync)
│ (API data, database queries)
│ └─ TanStack Query (React Query)
│ Handles: caching, background refetch, loading/error
│ Don't use useState + useEffect for server data
│
└─ Form state
└─ React Hook Form + Zod validation
(controlled inputs are fine for simple forms)
React 19 Quick Reference
| Feature | API | Purpose |
|---------|-----|---------|
| use() hook | use(promise) / use(context) | Await promises in render, read context conditionally |
| Actions | async function action(formData) | Async transitions with built-in pending st
Compatible Tools
Claude CodeCursorGitHub Copilot
Tags
Frontend
