useMemo, useCallback, and React.memo — The Full Picture
13 min read
Memoisation Done Right
Memoisation in React has three interlocking tools: useMemo caches a computed value, useCallback caches a function reference, and React.memo prevents a component from re-rendering when its props are shallowly equal. They work together — each one alone is often insufficient.
The reference equality problem
Objects and functions are compared by reference, not by value. A new function or object created during render is a different reference every time, so passing it as a prop always breaks React.memo. This is why useCallback and useMemo exist.
jsx
import { memo, useMemo, useCallback, useState } from "react";
// memo: skip re-render if props didn't change
const FilteredList = memo(function FilteredList({ items, onSelect }) {
console.log("FilteredList rendered");
return (
<ul>
{items.map(item => (
<li key={item.id} onClick={() => onSelect(item.id)}>{item.label}</li>
))}
</ul>
);
});
function App({ allItems }) {
const [query, setQuery] = useState("");
const [selected, setSelected] = useState(null);
// useMemo: only re-filter when allItems or query changes
const filteredItems = useMemo(
() => allItems.filter(i => i.label.toLowerCase().includes(query)),
[allItems, query]
);
// useCallback: stable reference for the memo-wrapped child
const handleSelect = useCallback((id) => {
setSelected(id);
}, []);
return (
<>
<input value={query} onChange={e => setQuery(e.target.value)} />
<FilteredList items={filteredItems} onSelect={handleSelect} />
<p>Selected: {selected}</p>
</>
);
}When NOT to memoize
- If the computation is fast (less than ~1 ms),
useMemooverhead may exceed the savings. - If the component rarely re-renders,
React.memoadds complexity for no gain. - If the dependency array changes on every render anyway, memoisation does nothing.
Profile first with the React DevTools Profiler. Memoisation is an optimization, not a default. Premature memoisation makes code harder to read and can even introduce bugs if dependencies are listed incorrectly.
Ready to test yourself?
Practice React— quiz & coding exercises