react · diff
git:20260630.95d2bc8 to git:20261007.4c4eb8c
87 added, 142 removed. Audit A to A.
---
name: react
description: >-
- Audits React and Next.js code for high-leverage runtime and rendering
- pitfalls, then routes to deep-dive references on useEffect anti-patterns,
- re-render causes, rendering model selection, React 19 APIs, and waterfall
- chains. Use when a .tsx or .jsx file is opened or reviewed, the user asks
- "is my React code good", mentions useEffect, re-renders, memoization, React
- Compiler, Server Components, Server Actions, SSR vs CSR, hydration,
- waterfalls, or bundle size. Triggers on React runtime/rendering reviews.
+ React component architecture and data-flow guidance for composition, state
+ ownership, Effects, Suspense, async UI, rendering behavior, and measured
+ performance. Use when building, recommending, or auditing React component APIs,
+ hooks, providers, transitions, rerenders, or server/client component boundaries.
+ Route Next.js-specific caching, routes, and App Router mechanics to
+ nextjs-app-architecture; route browser security, styling systems, and file
+ organization to frontend.
---
- # React Best Practices Audit
-
- Focused audit layer for React and Next.js runtime/rendering issues. Start with
- the universal checks, then route to the reference that matches the user's
- specific question.
-
- ## Universal Checks (no exceptions — run these every time)
+ # React Engineering
- These checks take seconds to scan for and catch common high-impact mistakes.
- Skip them only if you have already verified them in the same session.
+ Build React from ownership and composition: keep state with its owner, derive during
+ render, synchronize only with external systems, and introduce abstraction after real
+ variation appears. Match the user's request—build, recommend, or audit—without forcing a
+ full checklist onto focused work.
- 1. **Components defined inside other components**
- They are re-created on every render; state resets and memoization is lost.
- Extract to module scope.
+ ## Workflow
- 2. **Array index as `key` in dynamic lists**
- `key` is React's identity anchor. When lists reorder, insert, or delete, an
- index key reassigns identity to the wrong element. Use a stable ID from the
- data. Exception: truly static, never-reordered lists.
+ ### 1. Detect the React environment
- 3. **Derived state via `useState` + `useEffect`**
- If state is only a calculation from props/state, compute it during render
- (optionally `useMemo` for expensive work) instead of syncing with an Effect.
+ Inspect installed React and framework versions, compiler configuration, renderer,
+ routing/data libraries, and nearby conventions. Determine whether Server Components or
+ a client-only renderer are actually available. Use project or current primary docs for
+ version-sensitive mechanics.
- 4. **Data fetching in `useEffect` without cleanup**
- Slow responses can overwrite fresh data. Use cleanup/cancellation, TanStack
- Query, or Server Components so stale requests cannot win the race.
+ When the task depends on Next.js routes, Cache Components, Server Actions, App Router
+ file conventions, or framework caching, load `nextjs-app-architecture` instead of
+ restating those mechanics here.
- 5. **Unmemoized Context provider value**
- New object/function references make every consumer re-render. Memoize the
- provider value or split data and API contexts.
+ **Complete when:** React capabilities and framework ownership are known.
- 6. **Server Actions for client-side data reads**
- Server Actions serialize calls and are for mutations. Reads should use RSC,
- route handlers, or a client data layer that can parallelize and dedupe.
+ ### 2. Trace ownership and data flow
- 7. **`React.FC` and `forwardRef` as default patterns**
- Prefer plain function components. `React.FC` adds noise and misleading
- children behavior; React 19 makes `ref` a normal prop for new code. Load the
- React 19 reference for version-specific migration details.
+ Identify the component that owns each piece of state, the consumers that need it, the
+ server-cache boundary, URL state, form state, and external systems. Trace props and
+ context through the target interaction before changing abstractions.
- ## Ownership Boundary with Frontend
+ **Complete when:** every changed state and side effect has one named owner and data path.
- `react` owns React runtime/rendering issues: Effects, re-renders, Context,
- keys, Server Actions, hydration, React 19 APIs, waterfalls, and bundle/runtime
- performance. `frontend` owns broader TypeScript, UI accessibility, browser
- security, Next.js file boundaries, Tailwind/component API patterns, and frontend
- file structure.
+ ### 3. Choose the simplest composition
- ## Priority Checklist (run after universal checks)
+ Start top-down with plain components and explicit props. Extract when a responsibility,
+ real reuse, independent variation, or testing seam appears. Compound components,
+ providers, slots, and render callbacks must be earned by multiple compositions or
+ cross-tree coordination.
- Use this for full audits. The universal checks above catch the most common bugs;
- this checklist catches the rest.
+ **Complete when:** the component API exposes stable choices while volatile implementation
+ stays behind the boundary.
- **CRITICAL — Eliminating Waterfalls:**
- - [ ] No sequential awaits that could run in parallel
- - [ ] `Promise.all` for independent operations
- - [ ] API routes don't chain awaits unnecessarily
- - [ ] Strategic Suspense boundaries for streaming
+ ### 4. Model state and synchronization
- **CRITICAL — Bundle Size:**
- - [ ] Direct imports (no barrel files)
- - [ ] Dynamic imports for heavy components
- - [ ] Conditional module loading
- - [ ] Non-critical libs deferred
- - [ ] Preload based on user intent
+ Keep state local until coordination pressure requires the nearest shared owner. For a
+ composable family with real cross-tree coordination, use a provider contract that
+ separates state, actions, and imperative metadata from its implementation. Keep server
+ cache, URL state, form state, and application state in their appropriate systems.
- **HIGH — Server-Side Performance:**
- - [ ] Server Actions have authentication
- - [ ] RSC props minimized (only needed data)
- - [ ] Parallel data fetching via composition
- - [ ] `React.cache()` for per-request dedup
- - [ ] `after()` for non-blocking operations
- - [ ] No duplicate serialization
+ Effects synchronize with systems outside React. Derived values, interaction logic, and
+ state transitions remain in render, events, reducers, or the owning data layer.
- **MEDIUM-HIGH — Client Data Fetching:**
- - [ ] SWR/TanStack Query for automatic deduplication
- - [ ] Passive event listeners for scroll
- - [ ] Global event listeners deduplicated
- - [ ] `localStorage` versioned and minimal
+ **Complete when:** no state is mirrored without a synchronization requirement and every
+ Effect has an external system to synchronize.
- **MEDIUM — Re-render Optimization:**
- - [ ] Functional `setState` updates (no stale closures)
- - [ ] Lazy state initialization for expensive values
- - [ ] Narrow effect dependencies (primitives > objects)
- - [ ] `useTransition` for non-urgent updates
- - [ ] Derived state calculated during render (not via `useEffect`)
- - [ ] Interaction logic in event handlers (not state + effect)
- - [ ] `useRef` for transient values (mouse trackers, intervals)
- - [ ] Extract to memoized components when re-render scope is too broad
- - [ ] No unnecessary `useMemo` wrapping (prefer React Compiler if available)
+ ### 5. Design async and rendering behavior
- **MEDIUM — Rendering Performance:**
- - [ ] `content-visibility` for long lists
- - [ ] `useTransition` over manual loading states
- - [ ] Explicit conditional rendering (not `&&` with truthy non-booleans)
- - [ ] `suppressHydrationWarning` for known server/client differences
- - [ ] Prevent hydration mismatch without UI flicker
+ Place Suspense, transitions, optimistic state, pending feedback, and error recovery at
+ the owner of the waiting experience. Keep stable UI visible while replaceable content
+ waits. Let the dedicated framework skill decide route-level streaming and caching.
- **LOW-MEDIUM — JavaScript Performance:**
- - [ ] `Set`/`Map` for O(1) lookups
- - [ ] Early returns in functions
- - [ ] Cached repeated function calls
- - [ ] `toSorted()` over `sort()` for immutability
- - [ ] Avoid layout thrashing
- - [ ] Hoist `RegExp` creation outside render
+ **Complete when:** urgent interaction remains responsive and loading, success, failure,
+ and recovery behavior have clear owners.
- **LOW — Advanced Patterns:**
- - [ ] Event handlers in refs for stable references
- - [ ] `useEffectEvent` for stable callback refs
- - [ ] App initialization with module-level guards (not `useEffect`)
+ ### 6. Optimize from evidence
- ## Report Format
+ Fix waterfalls, unnecessary ownership breadth, and expensive rendering structure before
+ memoization or JavaScript micro-optimization. Use profiling, traces, bundle analysis, or
+ measured user impact. Account for the detected compiler before prescribing manual
+ memoization.
- For each violation:
- ```
- [PRIORITY] Rule Name
- File: path/to/file.tsx:line
- Issue: [description of the problem]
- Fix: [code example showing correct pattern]
- ```
+ **Complete when:** each optimization names a measured or structurally demonstrated cost
+ and verification uses the same signal.
- After the full checklist, provide:
- 1. **Violation Count by Priority** — CRITICAL: N · HIGH: N · MEDIUM: N · LOW: N
- 2. **Top 3 Highest-Impact Fixes** — brief description + expected improvement
- 3. **Overall Assessment** — Pass / Needs Work / Critical Issues
+ ### 7. Implement or report
- ## Stack Context — Determine Before Routing
+ - **Build:** implement the smallest coherent React change and run project checks.
+ - **Recommend:** explain the ownership and composition trade-off and choose a default.
+ - **Audit:** report evidence-backed findings without duplicating general PR review.
- Before loading references, determine which stack the user is on:
+ **Complete when:** behavior is verified, relevant tests and checks pass, and unresolved
+ framework or browser behavior is explicit.
- - **Next.js App Router** → RSC, Server Actions, streaming, and `react-19.md`
- action props / `useActionState` patterns apply
- - **Vite SPA (React Router / TanStack Router)** → no RSC, TanStack Query is the
- primary data layer, `tanstack-query.md` is the first reference to reach for
- - **Both** → `re-renders.md`, `useeffect-antipatterns.md`, `portals-and-stacking-context.md`,
- and `bundle-and-perf-investigation.md` are stack-agnostic
+ ## References
- If unsure, look at the imports: `next/` imports → App Router; `react-router-dom`
- or `@tanstack/react-router` → Vite SPA.
+ | Priority | Load when | Reference |
+ |---|---|---|
+ | 1 — High | Boolean prop growth, component API design, compound components, slots, variants, render props | `references/composition.md` |
+ | 1 — High | State placement, Context, providers, reducers, server cache, URL/form/application state | `references/state-and-data-flow.md` |
+ | 1 — High | `useEffect`, synchronization, derived state, stale closures, subscriptions, race conditions | `references/useeffect-antipatterns.md` |
+ | 1 — High | Suspense, transitions, optimistic updates, pending UI, async dependencies, error boundaries | `references/async-and-suspense.md` |
+ | 2 — Medium | Rerender diagnosis, state breadth, Context churn, React Compiler, memoization | `references/re-renders.md` |
+ | 2 — Medium | Slow startup or interaction, waterfalls, bundle analysis, profiling, Web Vitals | `references/bundle-and-perf-investigation.md` |
+ | 2 — Medium | Dialogs, popovers, tooltips, portals, stacking context, focus restoration | `references/portals-and-stacking-context.md` |
+ | 2 — Conditional | Detected React 19+ APIs, ref as prop, `use`, action hooks, form actions | `references/react-19.md` |
- ## References — Priority Table
+ ## Ownership Boundary
- Load the reference that matches the issue. Higher-priority references fix more
- users / cause more damage when missed — resolve CRITICAL before MEDIUM.
+ - `react` owns React composition, state, Effects, rendering, and async primitives.
+ - `frontend` owns trust boundaries, TypeScript surface contracts, accessibility baseline,
+ styling systems, browser behavior, security, and feature organization.
+ - `nextjs-app-architecture` owns Next.js-specific route, cache, streaming, and App Router
+ mechanics.
- | Priority | Load when | Reference |
- |----------|-----------|-----------|
- | 1 — Critical | React 19 APIs (`useActionState`, `useOptimistic`, `use()`), ref as prop, action props, `nuqs`, async transitions, Suspense sibling change | `references/react-19.md` |
- | 2 — Critical | sequential `await`, waterfall chains, `Promise.all`, Suspense streaming, `React.cache`, `after()`, parallel fetching | `references/waterfalls.md` |
- | 3 — Critical | slow initial load, bundle size, barrel file imports, code splitting, `rollup-plugin-visualizer`, Web Vitals, dynamic import | `references/bundle-and-perf-investigation.md` |
- | 4 — High | `useEffect` questions, "should I use an effect", stale closure, race condition, flickering UI, `useLayoutEffect` | `references/useeffect-antipatterns.md` |
- | 5 — High | SSR/CSR/SSG/ISR/RSC choice, "when should I use a Server Component", hydration mismatch, `suppressHydrationWarning` | `references/rendering-models.md` |
- | 6 — Medium-High | TanStack Query, `useQuery`, `queryOptions`, `select`, `staleTime`, `gcTime`, mutations, optimistic updates, query keys | `references/tanstack-query.md` |
- | 7 — Medium | `useMemo`, `useCallback`, `React.memo`, "why does this re-render", React Compiler, memoization decision | `references/re-renders.md` |
- | 8 — Medium | modal, dialog, tooltip, popover, z-index, "appears behind", portal, stacking context | `references/portals-and-stacking-context.md` |
+ ## Completion Gate
- ### When to load a reference
+ Before finishing:
- - Load the **highest-priority matching reference first** — fix CRITICAL issues before
- reaching for MEDIUM optimization references
- - A rule-level question (*"should I do X?"*) → load the reference for that category
- - A conceptual question (*"why does X happen?"*) → load the same reference; they
- include both explanation and the correct pattern
- - When multiple references match, load in priority order — they don't overlap
- - The universal checks + priority checklist above cover the most common violations
- without loading any reference; only load when depth is needed beyond the checklist
+ - version-sensitive guidance matches the detected React/framework version;
+ - component abstractions are justified by real variation or coordination;
+ - state and async behavior have explicit owners;
+ - Effects synchronize only with external systems;
+ - performance claims have evidence;
+ - the requested behavior and relevant checks are verified.