--- name: react-development description: React patterns, anti-patterns, and performance optimization. Use when writing React components, reviewing React code, or debugging React issues. --- # React Development Modern React patterns from the official docs and community expertise. ## Instructions When working with React code, apply these principles in order of importance: ### 1. Think in React Follow the 5-step process for building React UIs: 1. **Break UI into component hierarchy** — One component = one responsibility 2. **Build static version first** — Use props only, no state yet 3. **Find minimal state** — Ask: Does it change? Is it passed via props? Can it be computed? 4. **Identify where state lives** — Find closest common parent of components that need it 5. **Add inverse data flow** — Pass callbacks down to update parent state ### 2. Keep Components Pure Components must be pure functions during rendering: ```jsx // ❌ Mutates external variable let guest = 0; function Cup() { guest = guest + 1; return

Guest #{guest}

; } // ✅ Uses props function Cup({ guest }) { return

Guest #{guest}

; } ``` **Rules:** - Never mutate props, state, or context during render - Same inputs = same output - Side effects belong in event handlers or useEffect ### 3. State Management **Minimize state:** ```jsx // ❌ Redundant state const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const [fullName, setFullName] = useState(''); // redundant! // ✅ Compute during render const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const fullName = firstName + ' ' + lastName; ``` **Lift state up** when siblings need the same data — move to closest common parent. **Use key to reset state:** ```jsx // Forces fresh component instance when recipient changes ``` ### 4. Hooks Rules **Only call hooks at the top level:** - Never in loops, conditions, or nested functions - Never after early returns - React relies on consistent call order **Only call hooks from React functions:** - Function components or custom hooks only ### 5. Effects — Use Sparingly Effects are for synchronizing with external systems, not for state logic. **You DON'T need useEffect for:** | Scenario | Instead of Effect | Do This | |----------|-------------------|---------| | Transform data for render | `useEffect` + `setState` | Calculate during render | | Cache expensive calculations | `useEffect` + `setState` | `useMemo` | | Reset state on prop change | `useEffect` + `setState` | Use `key` prop | | Handle user events | `useEffect` watching state | Event handler directly | | Notify parent of changes | `useEffect` calling callback | Call in event handler | **When you DO need useEffect:** - Fetching data (with cleanup for race conditions) - Subscribing to events (with cleanup to unsubscribe) - Controlling non-React widgets - Connecting to external systems **Always add cleanup:** ```jsx useEffect(() => { const connection = createConnection(); connection.connect(); return () => connection.disconnect(); // cleanup }, []); ``` ### 6. Performance **Before reaching for memo:** 1. **Move state down** — Isolate state to components that use it 2. **Lift content up** — Pass expensive subtrees as `children` **Virtualize large lists** (50+ items): ```jsx import { FixedSizeList } from 'react-window'; {({ index, style }) =>
{items[index]}
}
``` **Code split routes:** ```jsx const Dashboard = lazy(() => import('./Dashboard')); }> ``` ### 7. Component Design Principles From "Writing Resilient Components": 1. **Don't stop the data flow** — Read props directly, don't copy to state 2. **Always be ready to render** — Don't assume render timing or frequency 3. **No component is a singleton** — Design as if rendered multiple times 4. **Keep local state isolated** — Only local if it wouldn't sync across copies ### 8. Context — Use Judiciously Good for: theming, current user, routing, widely-needed state. **Try these first:** 1. Pass props explicitly — clearer data flow 2. Extract components and use `children` — avoids prop drilling ```jsx // ❌ Prop drilling // ✅ Composition ``` ## Common Anti-Patterns | Anti-Pattern | Problem | Fix | |--------------|---------|-----| | Copying props to state | Stale data | Read props directly | | Effect chains | Cascading renders | Compute in event handlers | | Suppressing effect with refs | Hides bugs | Add proper cleanup | | Derived state in useState | Sync issues | Compute during render | | Missing keys in lists | Broken updates | Use stable unique IDs | | Index as key (for reorderable lists) | State mismatch | Use item IDs | ## Examples ### Well-Structured Component ```jsx function ProductList({ products, onSelect }) { // Derived state — computed, not stored const sortedProducts = useMemo( () => [...products].sort((a, b) => a.name.localeCompare(b.name)), [products] ); // Event handler — not useEffect function handleClick(product) { onSelect(product); } return ( ); } ``` ### Data Fetching with Cleanup ```jsx function UserProfile({ userId }) { const [user, setUser] = useState(null); useEffect(() => { let cancelled = false; async function fetchUser() { const data = await getUser(userId); if (!cancelled) setUser(data); } fetchUser(); return () => { cancelled = true; }; }, [userId]); if (!user) return ; return ; } ``` For detailed performance patterns, see [PERFORMANCE.md](PERFORMANCE.md).