Faster React: Memoization with React.memo, useMemo, and useCallback
Optimize re-renders with memoization to speed up heavy components. Great for lists, charts, and large data tables. Avoid premature optimization—profile before applying.
- Technology
- 2 min read
React re-renders components whenever their parent re-renders, even if the props don’t change.
👉 This can cause performance issues in large apps.
Memoization means: “Remember the result of a function until its inputs change.”
React.memo→ Memoizes components (UI rendering).useMemo→ Memoizes values.useCallback→ Memoizes functions.
Basics & Need
- Avoid unnecessary re-renders.
- Improve performance for expensive calculations.
- Keep child components lightweight when parent updates frequently.
How to Achieve It
Using React.memo
const Child = React.memo(({ name }) => { console.log("Rendered:", name); return <div>Hello {name}</div>;
});const Parent = () => { const [count, setCount] = React.useState(0); return ( <> <button onClick={() => setCount(count + 1)}>Increase</button> <Child name="Murli" /> </>
);
};
👉 Child won’t re-render when count changes, because name prop is the same.
Using useMemo (Memoize a Value)
const ExpensiveCalculation = ({ num }) => { const result = React.useMemo(() => { console.log("Calculating..."); return num * 2; // Imagine heavy calculation
}, [num]); return <p>Result: {result}</p>;
};
Using useCallback (Memoize a Function)
const Button = React.memo(({ onClick }) => { console.log("Button Rendered"); return <button onClick={onClick}>Click</button>;
});const Parent = () => { const [count, setCount] = React.useState(0); const increment = React.useCallback(() => { setCount((c) => c + 1);
}, []); return <Button onClick={increment} />;
};
👉 Without useCallback, a new function would be created each render → forcing Button to re-render.
Best Practices
- Use memoization only when needed (not everywhere).
- Use
React.memofor pure components (same props = same output). - Use
useMemofor heavy computations. - Use
useCallbackwhen passing callbacks to memoized children.
Real-World Examples
- E-commerce Product List → Product cards memoized to avoid re-render on cart updates.
- Dashboard with Charts → Expensive data transformations wrapped in
useMemo. - Forms → Memoize field components so typing in one field doesn’t re-render all.
Advantages
- Faster apps (less unnecessary rendering).
- Keeps UI responsive under heavy load.
- Works well with large data sets and complex UI trees.
Disadvantages
- Premature optimization can complicate code.
- Memoization itself consumes memory.
- Can confuse juniors (debugging memoized components is tricky).
Common Problems / Pitfalls
- Wrapping every component in
React.memo→ harms performance instead of helping. - Forgetting dependency arrays in
useMemo/useCallback→ stale or wrong data. - Overusing memoization on lightweight components → unnecessary complexity.
Summary Recommendation
Use memoization when:
- A component re-renders often with the same props.
- You have expensive computations.
- Passing functions to child components that don’t need to change.
👉 Avoid overuse — always profile before optimizing.