useMemo and useCallback for Performance
Memoize expensive calculations with useMemo and stable function references with useCallback to prevent unnecessary child re-renders.
useMemo and useCallback for Performance is a free Frontend Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
React's Default Behaviour
By default, React re-renders a component whenever its state or parent re-renders. Child components also re-render even if their props haven't changed. For most components this is fine — React is fast.
useMemo — Memoize Expensive Values
useMemo(fn, deps) caches the result of a computation. The function only runs when the dependencies change. Use it for expensive calculations that would be wasteful to repeat every render.
const expensiveResult = useMemo(() => {
return items.filter(item => item.category === category).sort((a, b) => a.price - b.price);
}, [items, category]);
// Only recalculates when items or category changesuseCallback — Memoize Functions
useCallback(fn, deps) returns a memoized function that maintains the same reference unless deps change. Use it when passing callbacks to deeply nested or memoized components.
const handleDelete = useCallback((id: string) => {
setItems(prev => prev.filter(item => item.id !== id));
}, []); // stable reference — empty deps because only setItems is used
<ItemList items={items} onDelete={handleDelete} />React.memo — Skip Re-renders
React.memo(Component) wraps a component so it only re-renders when its props change (shallow comparison). Combine with useCallback for stable callback props.
const MemoItem = React.memo(function Item({ text, onDelete }: ItemProps) {
console.log('Item rendered:', text); // only logs when props change
return <li>{text} <button onClick={onDelete}>×</button></li>;
});
// onDelete must be stable (from useCallback) for memo to helpWhen NOT to Optimise
Premature optimisation is a trap. useMemo and useCallback have a cost: the closure, the deps comparison. For cheap operations (filtering 10 items), the overhead outweighs the benefit. Optimise when you measure a real performance problem.
Profiling Before Optimising
Use the React DevTools Profiler to measure actual render times before adding memoization. The Profiler shows which components take the longest and how many times they render. Fix based on evidence, not assumption.
useMemo for Stable References
useMemo is also useful for keeping a reference stable — not for performance of the calculation itself, but to prevent a downstream memo or effect from re-running unnecessarily.
// Without useMemo, this creates a new array every render:
const config = useMemo(() => ({ endpoint: '/api', timeout: 5000 }), []);
// Without memoization, useEffect would re-run on every render:
useEffect(() => { initSDK(config); }, [config]);useCallback Dependencies
useCallback follows the same dependency rules as useEffect. Include every variable from the outer scope that the callback uses. State setters (from useState) are always stable and don't need to be in deps.
The useMemo + useCallback Relationship
useCallback(fn, deps) is equivalent to useMemo(() => fn, deps). They're the same mechanism — useCallback is just sugar for memoizing functions specifically.
List Item Memoization
A common pattern: memoize list item components when the list is large and re-renders frequently. Pass stable callbacks from useCallback to avoid defeating the memo.
const MemoRow = React.memo(Row);
const handleEdit = useCallback((id) => edit(id), []);
const handleDel = useCallback((id) => remove(id), []);
{rows.map(row => (
<MemoRow key={row.id} row={row} onEdit={handleEdit} onDelete={handleDel} />
))}Context Value Memoization
Memoize the value passed to a Context Provider to prevent all consumers from re-rendering whenever the Provider's parent re-renders.
const value = useMemo(() => ({ user, login, logout }), [user]);Quick Check
What is the purpose of useCallback?
Recap: useMemo and useCallback
useMemo caches expensive computed values. useCallback caches function references. React.memo skips re-renders when props don't change shallowly. Combine all three for component-level performance. Profile first — premature memoization adds complexity without benefit. Stable references prevent downstream effects and memos from re-running.
Frequently asked questions
Is the “useMemo and useCallback for Performance” lesson free?
Yes — the full text of “useMemo and useCallback for Performance” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.
What will I learn in “useMemo and useCallback for Performance”?
Memoize expensive calculations with useMemo and stable function references with useCallback to prevent unnecessary child re-renders. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “useMemo and useCallback for Performance” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Frontend Academy lesson?
Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- useContext for Global State
- useReducer for Complex State
- useMemo and useCallback for Performance
- Custom Hooks: Extracting Reusable Logic