Modern React best practices and anti-pattern catalog (2025-26). Use when writing, reviewing, or refactoring React components, hooks, and state management. Covers component design, state patterns, hooks misuse, performance, data fetching, and code organization.
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering-paved-path:react-best-practicesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Modern React conventions (2025-26). Covers what to do and what to avoid. For code examples, see [examples.md](examples.md).
Modern React conventions (2025-26). Covers what to do and what to avoid. For code examples, see examples.md.
Each rule is tagged with a severity for use by consuming agents:
children prop and composition over deep prop drillingThe #1 React anti-pattern. Look for it in every review.
useState — compute during renderuseState + useEffect to sync a computed value — just compute ituseMemo ONLY if the computation is expensive (measured, not assumed)useState — only values that change over time and affect the UIuseReducer instead of multiple useState callsBefore each useEffect, ask: Is there an external system being synchronized? If no, it's misused.
useEffect for derived state — compute during renderuseEffect for event handling — put logic in the event handleruseEffects that trigger each other — usually means derived stateMost useMemo/useCallback calls are unnecessary. Be skeptical:
useMemo — only for actually expensive computations (sorting large datasets, complex transforms)useCallback — only when the function is passed to a React.memo childcamelCase functions returning JSX are NOT React components. They break reconciliation, hooks, and dev tools.
renderThing() pattern — use <Thing /> component syntaxNew arrays, objects, and functions created inline in JSX props break React.memo on children.
useMemouseCallback (only when passed to memoized children)null are unnecessary — call the hook directlyuseApiQuery/useApiMutation core hooksstyle={} objectssm:, md:, lg:) for responsive designcomponents/ui/ over recreating common elementsreact-error-boundary package for function component-friendly APIresetKeys={[location.pathname]} so boundaries reset on navigationresetErrorBoundary in fallback UIkey when lists can be reordered, filtered, or modifiedMath.random() or other unstable values as keys — causes full unmount/remountkey on <React.Fragment key={id}>, not on a child{count && <Component />} when count can be 0 — renders literal 0{count > 0 && <Component />} or ternary insteadaria-label to icon-only buttons — without it, they're invisible to screen readersaria-describedby and aria-invalidaria-live="polite" for dynamic content updates (search results, notifications, toasts)React.lazy() + <Suspense> for route-level code splittingmanualChunks to split vendor bundles for better cachinglazy(() => import('./X')) — dynamic paths break build analysisuseEffect cleanup using AbortControllerbaseURL, default headers, and interceptorsref as a regular prop instead of using forwardRef (React 19+)memo/useMemo/useCallback unless measuredutils/ or components/ui/npx claudepluginhub syukpublic/dev-digest-ai-marketplace --plugin engineering-paved-pathGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
5plugins reuse this skill
First indexed Jul 20, 2026