Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply 62 React and Next.js performance optimization rules from Vercel Engineering
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/rerender-split-combined-hooks.md
1---2title: Split Combined Hook Computations3impact: MEDIUM4impactDescription: avoids recomputing independent steps5tags: rerender, useMemo, useEffect, dependencies, optimization6---78## Split Combined Hook Computations910When a hook contains multiple independent tasks with different dependencies, split them into separate hooks. A combined hook reruns all tasks when any dependency changes, even if some tasks don't use the changed value.1112**Incorrect (changing `sortOrder` recomputes filtering):**1314```tsx15const sortedProducts = useMemo(() => {16const filtered = products.filter((p) => p.category === category)17const sorted = filtered.toSorted((a, b) =>18sortOrder === "asc" ? a.price - b.price : b.price - a.price19)20return sorted21}, [products, category, sortOrder])22```2324**Correct (filtering only recomputes when products or category change):**2526```tsx27const filteredProducts = useMemo(28() => products.filter((p) => p.category === category),29[products, category]30)3132const sortedProducts = useMemo(33() =>34filteredProducts.toSorted((a, b) =>35sortOrder === "asc" ? a.price - b.price : b.price - a.price36),37[filteredProducts, sortOrder]38)39```4041This pattern also applies to `useEffect` when combining unrelated side effects:4243**Incorrect (both effects run when either dependency changes):**4445```tsx46useEffect(() => {47analytics.trackPageView(pathname)48document.title = `${pageTitle} | My App`49}, [pathname, pageTitle])50```5152**Correct (effects run independently):**5354```tsx55useEffect(() => {56analytics.trackPageView(pathname)57}, [pathname])5859useEffect(() => {60document.title = `${pageTitle} | My App`61}, [pageTitle])62```6364**Note:** If your project has [React Compiler](https://react.dev/learn/react-compiler) enabled, it automatically optimizes dependency tracking and may handle some of these cases for you.65