# Re-render Optimization (rerender-*) **Impact: MEDIUM.** Reducing unnecessary re-renders minimizes wasted computation and improves UI responsiveness. Rules below are from Vercel's `react-best-practices` skill (MIT, vercel-labs/agent-skills). Rule IDs match upstream filenames for traceability. --- ## `rerender-defer-reads` — Defer State Reads to Usage Point **Impact: MEDIUM (avoids unnecessary subscriptions)** Don't subscribe to dynamic state (searchParams, localStorage) if you only read it inside callbacks. **Incorrect (subscribes to all searchParams changes):** ```tsx function ShareButton({ chatId }: { chatId: string }) { const searchParams = useSearchParams() const handleShare = () => { const ref = searchParams.get('ref') shareChat(chatId, { ref }) } return } ``` **Correct (reads on demand, no subscription):** ```tsx function ShareButton({ chatId }: { chatId: string }) { const handleShare = () => { const params = new URLSearchParams(window.location.search) const ref = params.get('ref') shareChat(chatId, { ref }) } return } ``` --- ## `rerender-dependencies` — Narrow Effect Dependencies **Impact: LOW (minimizes effect re-runs)** Specify primitive dependencies instead of objects to minimize effect re-runs. **Incorrect (re-runs on any user field change):** ```tsx useEffect(() => { console.log(user.id) }, [user]) ``` **Correct (re-runs only when id changes):** ```tsx useEffect(() => { console.log(user.id) }, [user.id]) ``` **For derived state, compute outside effect:** ```tsx // Incorrect: runs on width=767, 766, 765... useEffect(() => { if (width < 768) { enableMobileMode() } }, [width]) // Correct: runs only on boolean transition const isMobile = width < 768 useEffect(() => { if (isMobile) { enableMobileMode() } }, [isMobile]) ``` --- ## `rerender-derived-state-no-effect` — Calculate Derived State During Rendering **Impact: MEDIUM (avoids redundant renders and state drift)** If a value can be computed from current props/state, do not store it in state or update it in an effect. Derive it during render to avoid extra renders and state drift. Do not set state in effects solely in response to prop changes; prefer derived values or keyed resets instead. **Incorrect (redundant state and effect):** ```tsx function Form() { const [firstName, setFirstName] = useState('First') const [lastName, setLastName] = useState('Last') const [fullName, setFullName] = useState('') useEffect(() => { setFullName(firstName + ' ' + lastName) }, [firstName, lastName]) return

{fullName}

} ``` **Correct (derive during render):** ```tsx function Form() { const [firstName, setFirstName] = useState('First') const [lastName, setLastName] = useState('Last') const fullName = firstName + ' ' + lastName return

{fullName}

} ``` References: [You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect) --- ## `rerender-derived-state` — Subscribe to Derived State **Impact: MEDIUM (reduces re-render frequency)** Subscribe to derived boolean state instead of continuous values to reduce re-render frequency. **Incorrect (re-renders on every pixel change):** ```tsx function Sidebar() { const width = useWindowWidth() // updates continuously const isMobile = width < 768 return