home / skills / ahonn / dotfiles / react-best-practices

react-best-practices skill

/.claude/skills/react-best-practices

This skill applies React best practices from react.dev and Vercel to review code, optimize performance, and improve state and effects.

npx playbooks add skill ahonn/dotfiles --skill react-best-practices

Review the files below or copy the command above to add this skill to your agents.

Files (20)
SKILL.md
4.5 KB
---
name: react-best-practices
description: "React best practices from react.dev and Vercel. Use when: (1) Reviewing React code, (2) Debugging performance issues, (3) Optimizing bundle size, (4) Writing effects or state logic. Triggers on: React performance, re-render, bundle size, waterfalls, code splitting, memo, useCallback, useMemo, useEffect, SSR flicker, initial load slow, React Compiler, state structure, immutable update, setState array object."
user-invocable: false
---

# React Best Practices

Performance patterns and guidelines from react.dev and Vercel Engineering.

## Quick Reference (Priority Order)

### CRITICAL - Must Follow

| Rule | Impact | Reference |
|------|--------|-----------|
| Avoid unnecessary effects | Render cycles, bugs | [effect-pitfalls.md](references/effect-pitfalls.md) |
| Eliminate waterfalls | First paint, TTI | [async-waterfall-elimination.md](references/async-waterfall-elimination.md) |
| Parallel data fetching | Load time | [async-parallel-requests.md](references/async-parallel-requests.md) |
| Avoid barrel imports | Bundle size | [bundle-barrel-imports.md](references/bundle-barrel-imports.md) |

### HIGH - Strongly Recommended

| Rule | Impact | Reference |
|------|--------|-----------|
| React Compiler (19+) | Auto memoization | [react-compiler.md](references/react-compiler.md) |
| Dynamic imports | Code splitting | [bundle-dynamic-import.md](references/bundle-dynamic-import.md) |
| Preload on user intent | Perceived latency | [bundle-preload.md](references/bundle-preload.md) |
| Strategic memo() | Render perf | [rerender-memo-strategy.md](references/rerender-memo-strategy.md) |
| Server caching | Server response | [server-cache-patterns.md](references/server-cache-patterns.md) |

### MEDIUM - Recommended

| Rule | Impact | Reference |
|------|--------|-----------|
| State structure | Maintainability | [state-structure.md](references/state-structure.md) |
| Immutable updates | Avoid mutation bugs | [immutable-updates.md](references/immutable-updates.md) |
| Context splitting | Avoid rerenders | [rerender-context-splitting.md](references/rerender-context-splitting.md) |
| startTransition | UI responsiveness | [rerender-transitions.md](references/rerender-transitions.md) |
| Set/Map lookups | O(1) vs O(n) | [js-set-map-lookups.md](references/js-set-map-lookups.md) |
| Key patterns | List rendering | [rendering-key-patterns.md](references/rendering-key-patterns.md) |

### LOW - Nice to Have

| Rule | Impact | Reference |
|------|--------|-----------|
| content-visibility | Long list render | [rendering-content-visibility.md](references/rendering-content-visibility.md) |
| Hydration flicker | SSR stability | [rendering-hydration-flicker.md](references/rendering-hydration-flicker.md) |
| Hoist static JSX | Avoid re-creation | [rendering-hoist-static-jsx.md](references/rendering-hoist-static-jsx.md) |

---

## Quick Decision Tree

```
React Issue?
├── Writing useEffect?
│   └── Check if needed → effect-pitfalls.md (CRITICAL)
├── Designing state?
│   └── Follow 5 principles → state-structure.md
├── Updating state?
│   └── Use immutable patterns → immutable-updates.md
├── Using React 19+?
│   └── Enable React Compiler → react-compiler.md
├── Slow initial load?
│   ├── Check for waterfalls → async-waterfall-elimination.md
│   ├── Check bundle size → bundle-barrel-imports.md
│   └── Preload on intent → bundle-preload.md
├── Slow interactions?
│   ├── Check re-renders → rerender-memo-strategy.md
│   ├── Check Context usage → rerender-context-splitting.md
│   └── Use transitions → rerender-transitions.md
├── Long list jank?
│   └── Use content-visibility → rendering-content-visibility.md
├── SSR flicker?
│   └── Inline script pattern → rendering-hydration-flicker.md
└── Slow server?
    └── Check caching → server-cache-patterns.md
```

---

## Reference Files

| File | Content |
|------|---------|
| [hooks-guide.md](references/hooks-guide.md) | Hook patterns, decision guides, pitfalls |
| [effect-pitfalls.md](references/effect-pitfalls.md) | When NOT to use useEffect |
| [react-compiler.md](references/react-compiler.md) | React 19+ auto memoization |
| [state-structure.md](references/state-structure.md) | 5 principles for state design |
| [immutable-updates.md](references/immutable-updates.md) | Array/object update patterns |
| [references/](references/) | All reference files (19 total) |

**Search rules**: `grep -l "keyword" references/`

Overview

This skill codifies React best practices drawn from react.dev and Vercel engineering. It helps reviewers and developers find concrete fixes for performance, bundle size, and state/effect problems. Use it as a checklist when auditing React apps or diagnosing slow renders and hydration issues.

How this skill works

The skill inspects common React pain points: unnecessary effects, render waterfalls, bundle bloat, and poor state updates. It maps issues to targeted recommendations (e.g., eliminate waterfalls, enable the React Compiler, split context, use immutable updates) and points to concrete actions like dynamic imports, memoization, and parallel data fetching. It also provides a short decision tree to prioritize fixes by impact.

When to use it

  • Reviewing React code for performance or correctness
  • Debugging slow initial load, hydration flicker, or TTI regressions
  • Optimizing bundle size and code-splitting strategy
  • Writing or refactoring useEffect, state updates, or context logic
  • Addressing excessive re-renders or UI jank during interactions

Best practices

  • Avoid unnecessary useEffect calls; prefer deriving from props/state when possible
  • Eliminate async waterfalls by fetching in parallel and using suspense where appropriate
  • Enable the React Compiler (React 19+) to leverage automatic memoization and smaller runtime cost
  • Use dynamic imports and preload on user intent to reduce initial bundle size and perceived latency
  • Design state with clear ownership and immutable update patterns to prevent bugs and needless re-renders
  • Split Context and hoist static JSX to limit component re-renders and improve rendering stability

Example use cases

  • A page with slow first paint caused by sequential data fetching — parallelize requests and remove waterfall awaits
  • Components re-rendering too often — audit props, memoize child components, and split context providers
  • Large bundle with many barrel imports — convert heavy modules to dynamic imports and preload on intent
  • useEffect runs on every render — verify dependency list or replace effect with derived state
  • SSR hydration flicker — inline critical styles/scripts and ensure consistent server/client render output

FAQ

When should I prefer memo() versus rewriting state?

Prefer fixing state shape and prop stability first; use memo() to optimize pure components when props are stable and re-renders remain expensive.

How do I spot an async waterfall quickly?

Look for sequential awaits in route data loaders or useEffect chains. Replace with Promise.all or start requests earlier (e.g., in parallel hooks or preload triggers).