About react
react is a set of practical guidelines for writing and reviewing React code. It covers Effects, rendering performance, data fetching, forms, and React 19 migration, and includes a review checklist.
Key features
- 01Effect usage and cleanup guidance
- 02Re-render and state management advice
- 03Data fetching and request parallelization
- 04React 19 forms and migration notes
- 05Performance tips and review checklist
Use cases
- 01Check whether components use Effects unnecessarily
- 02Review cleanup for subscriptions, listeners, and requests
- 03Improve data fetching and component rendering
- 04Plan a React 19 upgrade and form changes
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ xgent-ai/ skills --skill reactAfter installing, type/reactin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/actions.mdcomponent-patterns.mddata-fetching.mdeffect-patterns.mdjs-performance.mdreact19-migration.mdrendering-performance.mdrerender-optimization.mdDetails
From the project READMEReact Best Practices
Apply these guidelines when writing or reviewing React code.
Reference Files
Read ALL relevant references in the same turn, in parallel. Cite them when giving feedback:
- Effect patterns: When you don't need an Effect, dependency rules, cleanup, subscriptions,
useSyncExternalStore, one-time initialization - Re-render optimization:
memo/useMemo/useCallback, derived state, functional updates, lazy init,useDeferredValue,startTransition,useEffectEvent - Component patterns: Refs,
useImperativeHandle, custom hook rules, controlled vs. uncontrolled, composition over prop drilling,flushSync - Data fetching: Parallelizing requests, Suspense boundaries,
use()and stable promise sources, request deduplication, passive listeners,localStorageversioning - Rendering performance:
content-visibility, hydration mismatches, resource hints, script loading, SVG animation,Activity,useTransition - JS performance: Layout thrashing,
Set/Maplookups, index maps, single-pass iteration,toSorted,requestIdleCallback - Actions:
<form action>,useActionState,useFormStatus,useOptimistic— pending, error, and optimistic state for mutations - React 19 migration: Upgrading from 18 — root API,
findDOMNode,forwardRef,defaultProps, legacy context, string refs, propTypes, JSX transform, TypeScript types,act/test-utils, StrictMode test counts
You Might Not Need an Effect
Effects are an escape hatch from React. They synchronize with external systems. If no external system is involved, you probably don't need one.
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
Do need an Effect: non-React widgets and browser APIs, subscriptions (prefer useSyncExternalStore), analytics that fire because a component displayed, data fetching with cleanup (prefer a data library).
Don't need an Effect: transforming data for rendering, handling user events, deriving state, chaining state updates, notifying a parent, resetting state.
Quick Reference
Effects
| Situation | Don't | Do |
|---|---|---|
| Derived state from props/state | useState + useEffect | Calculate during render |
| Expensive calculation | useEffect to cache | useMemo |
| Reset state on prop change | useEffect + setState | key prop |
| Response to a user event | useEffect watching state | Event handler |
| Notify parent of a change | useEffect calling onChange | Call it in the event handler |
| Subscribe to an external store | Manual useEffect subscription | useSyncExternalStore |
| Fetch data | useEffect without cleanup | ignore flag, or a data library |
| Effect re-runs every render | Object/function in deps | Move creation inside the effect |
| Missing dependency | eslint-disable exhaustive-deps | Functional update or useEffectEvent |
| One-time app init | useRef guard | Module-level flag |
Re-renders
- Never define a component inside another component — it remounts every render
- Use functional
setStatewhen the next state depends on the previous one useState(() => expensive())for expensive defaults; the plain form runs every render- Don't wrap simple boolean/primitive expressions in
useMemo - Split combined
useMemo/useEffect— one concern each - Values that change often but aren't rendered (mouse position, flags) belong in refs
- If React Compiler is enabled, skip manual
memo/useMemo/useCallback
Data fetching
Promise.all()for independent requests; chain per item for dependent ones- Move
awaitpast early returns and behind cheap synchronous guards - One shared request per endpoint (SWR / React Query), not one per component instance
- Every fetch effect needs an
ignoreflag orAbortController - Promises passed to
use()come from a loader, cache, library, or Server Component — never created in render
Forms and mutations (React 19)
<form action={fn}>overonSubmit+preventDefault;useActionStateover a loading/error reducer- Return expected errors from the action as state; thrown errors go to the error boundary
useFormStatusis imported fromreact-domand only reads a parent<form>- Seed
useOptimisticwith confirmed state and call its setter inside an Action - After
awaitinside an Action, wrap state updates in anotherstartTransition
Upgrading to React 19
- Run
npx codemod@latest react/19/migration-recipefirst; the upgrade PR changes API surface only forwardRefstill works —refis a plain prop; convert opportunisticallydefaultPropsare ignored on function components but still work on class components- StrictMode still double-runs effects; what changed is
useMemo/useCallbackresult reuse and double-invoked ref callbacks
Performance
- Measure before optimizing — profile, don't guess
- Batch DOM writes, then read once; interleaving forces reflow
Set/Mapfor repeated lookups; one pass instead of chained.filter().map().toSorted()on props and state —.sort()mutates- Defer analytics and prefetching with
requestIdleCallback
Review Checklist
- Does every
useEffectsynchronize with an external system? If not, propose the alternative. - Are dependency arrays complete, with no lint suppressions?
- Does every subscription, listener, timer, and fetch have cleanup?
- Is any state redundant — derivable from other props or state?
- Are components defined at module scope?
- Are independent async calls parallelized?
- Are mutating array methods used on props or state?
- Is every promise passed to
use()stable across renders? - On React 19: are forms using Actions with errors returned as state, and are removed APIs (
findDOMNode, string refs, legacy context,test-utils) gone?