useMemo Hook
In this page:
const memoizedValue = useMemo(() => {
return expensiveCalculation(dependency);
}, [dependency]);
Memoizing an Expensive Calculation
useMemo(calculateValue, dependencies) runs calculateValue and caches its result. On future renders, if the dependencies haven't changed, React reuses the cached result instead of recalculating it, saving the cost of an expensive computation.
Example: Memoizing an Expensive Calculation
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function ExpensiveList({ items }) {
const sorted = React.useMemo(() => {
console.log("Sorting...");
return [...items].sort();
}, [items]);
return <ul>{sorted.map((item, i) => <li key={i}>{item}</li>)}</ul>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<ExpensiveList items={["banana", "apple", "cherry"]} />);
</script>
</body>
</html>
How the Dependency Array Controls Recalculation
Just like useEffect, useMemo takes a dependency array as its second argument. React compares each dependency to its previous value, and only re-runs the calculation function if at least one of them has changed since the last render.
[] means the value is only ever calculated once, which is wrong if the calculation depends on props or state that can change.Example: How the Dependency Array Controls Recalculation
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function PriceCalculator({ quantity, price }) {
const total = React.useMemo(() => {
console.log("Recalculating total...");
return quantity * price;
}, [quantity, price]);
return <p>Total: ${total}</p>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<PriceCalculator quantity={3} price={9.99} />);
</script>
</body>
</html>
When NOT to Use useMemo
For cheap calculations -- simple arithmetic, short string formatting -- the overhead of useMemo's own bookkeeping can outweigh any benefit. useMemo is a targeted optimization tool for genuinely expensive work, not a default wrapper for every derived value.
Example: When NOT to Use useMemo
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function SimpleGreeting({ name }) {
// No useMemo needed here -- this is trivially cheap
const greeting = `Hello, ${name}!`;
return <p>{greeting}</p>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<SimpleGreeting name="Sam" />);
</script>
</body>
</html>
- Wrapping every single calculation in useMemo, even cheap ones, adding overhead without real benefit.
- Forgetting to list a value used inside the memoized calculation in the dependency array.
- Expecting useMemo to prevent a component from re-rendering -- it only memoizes a calculated VALUE, not the render itself.
- useMemo caches the result of an expensive calculation between renders.
- It only recalculates when one of its listed dependencies changes.
- It's meant for genuinely expensive computations, not for optimizing everything by default.
- Overusing useMemo can add complexity without meaningful performance benefit.
Available since React 16.8, when Hooks were introduced.
Chapter Quiz — Complete all 12 topics to unlock
0/12 topics done
Complete these topics first: