|
| 1 | +--- |
| 2 | +name: react-rerender-mental-models |
| 3 | +description: Correct mental models for React re-renders and memoization. Use this skill when writing, reviewing, or optimizing React components to avoid common misconceptions about performance. Debunks the myth that "props cause re-renders" and teaches when memoization actually helps. |
| 4 | +license: MIT |
| 5 | +metadata: |
| 6 | + author: freighter |
| 7 | + version: "1.0.0" |
| 8 | +--- |
| 9 | + |
| 10 | +# React Re-render Mental Models |
| 11 | + |
| 12 | +A practical guide to understanding how React re-renders actually work, debunking common misconceptions, and knowing when optimization is truly needed. |
| 13 | + |
| 14 | +## Core Philosophy |
| 15 | + |
| 16 | +> "Trust React to be fast. Write simple code. Measure when something actually feels slow. Optimize based on data, not fear." |
| 17 | +
|
| 18 | +## When to Apply |
| 19 | + |
| 20 | +Reference these guidelines when: |
| 21 | +- Writing new React components |
| 22 | +- Reviewing code for performance issues |
| 23 | +- Deciding whether to add React.memo, useCallback, or useMemo |
| 24 | +- Debugging perceived "slowness" in React apps |
| 25 | +- Refactoring component architecture |
| 26 | + |
| 27 | +## Rule Categories |
| 28 | + |
| 29 | +| Category | Prefix | Description | |
| 30 | +|----------|--------|-------------| |
| 31 | +| Mental Models | `mental-model-` | Correct understanding of how React works | |
| 32 | +| Anti-Patterns | `anti-pattern-` | Common mistakes to avoid | |
| 33 | +| When to Memoize | `when-to-memo-` | Profile-driven optimization guidance | |
| 34 | +| Architecture | `architecture-` | Component structure patterns | |
| 35 | + |
| 36 | +## Quick Reference |
| 37 | + |
| 38 | +### Mental Models (Foundational) |
| 39 | + |
| 40 | +- `mental-model-parent-triggers` - Props don't trigger re-renders; parent re-renders do |
| 41 | +- `mental-model-render-vs-commit` - Render ≠ Commit; renders are cheap, commits touch DOM |
| 42 | + |
| 43 | +### Anti-Patterns (Avoid These) |
| 44 | + |
| 45 | +- `anti-pattern-premature-memo` - Don't memoize without profiling first |
| 46 | +- `anti-pattern-memoization-trap` - Real bottlenecks are often not re-renders |
| 47 | + |
| 48 | +### When to Memoize (Use Sparingly) |
| 49 | + |
| 50 | +- `when-to-memo-context-values` - Stabilize context object references |
| 51 | +- `when-to-usecallback` - Only needed when child is already memoized |
| 52 | + |
| 53 | +### Architecture (Prefer These) |
| 54 | + |
| 55 | +- `architecture-local-state` - Keep state close to where it's used |
| 56 | +- `architecture-composition` - Component structure prevents re-renders naturally |
| 57 | + |
| 58 | +## What Actually Triggers Re-renders |
| 59 | + |
| 60 | +1. **Component's own state changes** (useState, useReducer) |
| 61 | +2. **Parent component re-renders** (cascades to all children) |
| 62 | +3. **Context value changes** (for consumers of that context) |
| 63 | + |
| 64 | +**Props are NOT on this list.** Props are inputs to a render that's already happening—they don't schedule one. |
| 65 | + |
| 66 | +## The Performance Debugging Flow |
| 67 | + |
| 68 | +``` |
| 69 | +1. Something feels slow |
| 70 | +2. Open React DevTools Profiler |
| 71 | +3. Record the interaction |
| 72 | +4. Look for components with 50ms+ render times |
| 73 | +5. If found → consider memoization |
| 74 | +6. If not found → the problem is elsewhere: |
| 75 | + - API calls firing too often |
| 76 | + - Unoptimized images |
| 77 | + - Too many DOM nodes |
| 78 | + - CSS animations triggering layout |
| 79 | +``` |
| 80 | + |
| 81 | +## React 19 Compiler |
| 82 | + |
| 83 | +This project runs React 19. The **React Compiler** (formerly React Forget) is |
| 84 | +an opt-in build-time tool that statically analyzes components and automatically |
| 85 | +inserts the equivalent of `useMemo`, `useCallback`, and `React.memo`. It is |
| 86 | +**not enabled by default** — it requires `babel-plugin-react-compiler` (or the |
| 87 | +SWC equivalent) to be installed and configured. |
| 88 | + |
| 89 | +- If the compiler is **enabled in this project**: skip manual memoization. The |
| 90 | + compiler tracks data flow within each component and caches results at a more |
| 91 | + granular level than hand-written hooks. If the compiler opts out a specific |
| 92 | + component (e.g. due to side effects during render), fix the component rather |
| 93 | + than adding manual memo. |
| 94 | +- If the compiler is **not enabled** (current default): follow the rules below, |
| 95 | + but prefer architecture fixes (local state, composition) over adding |
| 96 | + memo/useCallback. |
| 97 | + |
| 98 | +Regardless of compiler status, the mental models and architecture rules in this |
| 99 | +skill still apply — composition and local state are always better than relying |
| 100 | +on memoization (auto or manual). Re-render triggers remain the same either way. |
| 101 | + |
| 102 | +## How to Use |
| 103 | + |
| 104 | +Read individual rule files for detailed explanations and code examples: |
| 105 | + |
| 106 | +``` |
| 107 | +rules/mental-model-parent-triggers.md |
| 108 | +rules/anti-pattern-premature-memo.md |
| 109 | +rules/architecture-local-state.md |
| 110 | +``` |
| 111 | + |
| 112 | +Each rule file contains: |
| 113 | +- Brief explanation of why it matters |
| 114 | +- Incorrect code example with explanation |
| 115 | +- Correct code example with explanation |
0 commit comments