🧠 Introduction
Ever noticed your React component re-rendering even when nothing seems to have changed? Or a table, chart, or dropdown becoming sluggish when the parent component updates frequently?
This is where React memoization comes to the rescue.
In this post, we’ll explore the three main tools React offers to avoid unnecessary re-renders and optimize performance:
React.memo
useCallback
useMemo
And instead of just theory, I’ll share real examples from my own experience on when to use them — and when to avoid them.
🔁 React.memo
– Skip Re-renders for Pure Components
React.memo
is a higher-order component that wraps around your functional component and skips re-rendering it if props haven’t changed.
Use it for:
- Presentational components
- Cards, tables, list items
- Any component that receives stable props
Example:
const UserCard = React.memo(({ name }) => {
console.log("Rendering:", name);
return <div>{name}</div>;
});
Even if the parent re-renders, UserCard
won’t re-render unless the name
prop changes.
🧠 useMemo
– Cache Expensive Calculations
useMemo
is ideal when you have a heavy computation or derived value that doesn’t need to be recalculated every render.
Use it for:
- Filtering or sorting large arrays
- Deriving values from props or state
- Avoiding expensive recalculations
Example:
const sortedList = useMemo(() => {
return items.sort((a, b) => a.value - b.value);
}, [items]);
Without useMemo
, items.sort()
would run on every render, even if items
didn’t change.
🪝 useCallback
– Memoize Functions
When you pass functions as props to a memoized child component, they can cause unnecessary re-renders if recreated every render.
useCallback
returns the same function instance unless dependencies change.
Example:
const handleClick = useCallback(() => {
console.log("Clicked!");
}, []);
⚠️ When Not to Use Memoization
Optimization is powerful, but don’t overdo it.
Avoid using React.memo
, useMemo
, or useCallback
if:
- Components are small and cheap to render
- Props or state change frequently anyway
- It adds unnecessary complexity
Rule: Profile first, optimize second.
✅ Real-World Case
Recently, I had a dynamic form with multiple inputs and dropdowns.
Whenever the parent updated (like from a context), the entire form re-rendered, making it slow.
Solution:
- Wrapped each field block with
React.memo
- Memoized dropdown options using
useMemo
- Used
useCallback
foronChange
handlers
Result:
Reduced render count by ~40%, resulting in a much smoother experience.
📚 Key Takeaways
Tool | Use Case |
---|---|
React.memo |
Prevent re-rendering of child components if props haven’t changed |
useMemo |
Cache computed values |
useCallback |
Cache functions passed to children |
🧠 Final Thoughts
Memoization is like salt — a little can enhance the experience, too much can ruin it.
Use the React DevTools Profiler to identify where optimization is needed, then memoize with intent.
Top comments (0)