React is powerful — but if you’ve ever noticed your app getting sluggish as it grows, you’re not alone. Re-renders, expensive calculations, and unnecessary updates can quietly eat away at your app’s performance.
In this post, we’ll explore how hooks like useMemo and useCallback can make your app faster and more efficient — and when not to use them.
🧠 Understanding React Re-renders
React’s rendering behavior is simple: whenever a component’s state or props change, it re-renders.
But sometimes, that re-render trickles down to child components that didn’t need to update — causing performance issues.
Example:
function Parent({ count }) {
return (
<>
<HeavyComponent />
<DisplayCount count={count} />
</>
);
}
Even if only count changes, HeavyComponent might re-render — unnecessarily.
⚙️ useMemo: Cache Expensive Computations
useMemo helps you memoize (remember) expensive calculations so they don’t re-run on every render.
const filteredList = useMemo(() => {
return list.filter(item => item.active);
}, [list]);
💡 When to use it:
- Heavy loops or calculations
- Derived data that’s reused multiple times
- Expensive object or array creation
🚫 When NOT to use it:
- For lightweight operations — it adds unnecessary overhead.
🔁 useCallback: Stabilize Function References
useCallback is like useMemo but for functions.
It returns a memoized version of the callback that only changes when its dependencies change.
const handleClick = useCallback(() => {
console.log("Clicked!");
}, []);
💡 Why it matters:
When you pass functions as props to child components, React might re-render them unnecessarily.
Using useCallback ensures the function reference stays the same — reducing renders.
🚀 Beyond useMemo and useCallback
Here are other ways to level up your React performance:
- React.memo() – Wrap functional components to prevent re-rendering if props haven’t changed.
-
Code Splitting – Load only what’s needed using
React.lazyandSuspense. -
Virtualization – Use libraries like
react-windowfor large lists. - Avoid Anonymous Functions in JSX – They create new references on every render.
- Profile Your App – Use the React DevTools Profiler to see where time is being spent.
🧩 Putting It All Together
Performance optimization is about balance — don’t overuse these hooks.
Start by identifying real bottlenecks, and use memoization where it counts.
Remember: clean, readable code beats micro-optimizations most of the time.
💬 Have you used useMemo or useCallback in your projects?
Share your favorite optimization tips in the comments!
Top comments (1)
With the new react compiler (react.dev/learn/react-compiler) this (hopefully) will become unnecessary.