As a React developer, optimizing performance is crucial. Two tools that help with this are useMemo
and memo
. Let’s break them down with easy examples.
What is useMemo
?
useMemo
is a React Hook that remembers (or “memoizes”) the result of a calculation. This means it stores the result and only recalculates it when certain values (dependencies) change. This is great for expensive calculations that don’t need to be repeated every time a component re-renders.
Simple Example:
import React, { useMemo } from 'react';
function ExpensiveCalculation({ a, b }) {
// Only recalculate when 'a' or 'b' changes
const result = useMemo(() => {
console.log('Calculating...');
return a * b; // Expensive calculation
}, [a, b]);
return <div>Result: {result}</div>;
}
function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Re-render ({count})</button>
<ExpensiveCalculation a={5} b={10} />
</div>
);
}
What happens here?
ExpensiveCalculation
calculatesa * b
(5 * 10 = 50).- Even when the parent (
App
) re-renders (e.g., when you click the button),ExpensiveCalculation
won’t recalculate unlessa
orb
changes. - You’ll only see “Calculating…” once, not on every click.
What is memo
?
memo
is a higher-order component that prevents a component from re-rendering if its props haven’t changed. It’s like a “smart” component that only updates when necessary.
Simple Example:
import React, { memo } from 'react';
const Greeting = memo(({ name }) => {
console.log('Greeting rendered!');
return <div>Hello, {name}!</div>;
});
function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Re-render ({count})</button>
<Greeting name="Alice" />
</div>
);
}
What happens here?
Greeting
only re-renders if itsname
prop changes.- Even when
count
changes (andApp
re-renders),Greeting
doesn’t re-render becausename
(“Alice”) stays the same. - You’ll only see “Greeting rendered!” once, not on every click.
useMemo
vs memo
: Key Differences
Feature | useMemo | memo |
---|---|---|
What it does | Memoizes values (e.g., calculations) | Memoizes components (prevents re-renders) |
How it works | Uses a dependency array ([a, b] ) | Uses prop comparison |
Best for | Expensive calculations | Components with stable props |
When to Use useMemo
- Slow calculations: If a computation takes time (e.g., filtering a big list), use
useMemo
to avoid repeating it. - Derived data: If you compute something from props/state (e.g.,
totalPrice = items.reduce(...)
),useMemo
can help.
Example:
const total = useMemo(() => {
return items.reduce((sum, item) => sum + item.price, 0);
}, [items]); // Only recalculate if 'items' changes
When to Use memo
- Stable props: If a child component receives the same props repeatedly,
memo
can skip re-rendering. - Performance issues: If a component is slow to render,
memo
might help.
Example:
const UserCard = memo(({ user }) => {
return <div>{user.name}</div>;
});
// Only re-renders if 'user' changes
<UserCard user={{ id: 1, name: "Bob" }} />
Common Mistakes & Tips
1. Don’t overuse them!
- Only use
useMemo
/memo
when you see a real performance issue. - Premature optimization can make code harder to read.
2. memo
and objects/arrays
memo
does a shallow compare of props. If you pass a new object/array every time, it may not work as expected.- Fix: Use
useMemo
for object/array props or a custom comparison function.
3. Missing dependencies in useMemo
- Always include all variables used in the calculation in the dependency array.
- Example:
const result = useMemo(() => a * b, [a, b]); // ✅ Correct
Combining useMemo
and memo
You can use both together for maximum optimization!
import React, { useMemo, memo } from 'react';
const Calculator = memo(({ a, b }) => {
const result = useMemo(() => {
console.log('Calculating...');
return a + b;
}, [a, b]);
return <div>Result: {result}</div>;
});
function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Re-render ({count})</button>
<Calculator a={3} b={7} />
</div>
);
}
What happens here?
Calculator
won’t re-render unlessa
orb
changes (thanks tomemo
).- Even if it does re-render, the calculation is memoized (thanks to
useMemo
).
FAQs
Q1: What’s the difference between useMemo
and useCallback
?
useMemo
memoizes values (e.g.,const x = 1 + 2
).useCallback
memoizes functions (e.g.,const fn = () => {...}
).
Q2: Can I use memo
with class components?
- No,
memo
is for functional components. UsePureComponent
for classes.
Q3: Does useMemo
prevent re-renders?
- No, it only memoizes values. To prevent re-renders, use
memo
.
Q4: When should I avoid useMemo
?
- Avoid it for simple calculations (e.g.,
a + b
). The overhead might outweigh the benefit.
Conclusion
useMemo
: For optimizing calculations (values).memo
: For optimizing components (re-renders).- Use them wisely—only when needed!
Reading Further
- React Design Patterns
- useTransition Hook in React
- useDeferredValue Hook in React
- useSyncExternalStore Hook in React
Happy coding! 🚀