Hands-on practice for this lecture. Work through the exercises and quizzes to reinforce what you've learned.
Exercise 1 of 2
Four useMemo scenarios. Decide which ones are worth the overhead and which ones are premature optimization — learn the signals that make the call obvious.
Four memoization decisions. For each: is this useMemo worth the overhead?
const doubled = useMemo( () => value * 2, [value] );
Is this useMemo worth it?
const results = useMemo(
() => items.filter(item =>
item.toLowerCase().includes(query)
),
[items, query]
);
// items.length = 50,000Is this useMemo worth it?
const style = useMemo(
() => ({ color: 'red', fontSize: 14 }),
[]
);Is this useMemo worth it?
const tree = useMemo( () => buildTreeFromNodes(rawData), [rawData] ); // buildTreeFromNodes: O(n log n), n ≈ 10,000
Is this useMemo worth it?
0/4 answered
💡 The rule of thumb: measure first. If a computation runs in under 1ms, useMemo adds more overhead than it saves. Use it for genuinely expensive derivations — sort/filter on large arrays, complex tree transforms, heavy math.
Exercise 2 of 2
Live editor: an expensive filter reruns on every render including unrelated ones. Wrap it in useMemo and watch the console confirm it only runs when the query changes.
Task
The filter is expensive (80ms intentional block). Right now it runs on every render — including when you toggle dark mode, which has nothing to do with filtering.
Wrap expensiveFilter in useMemo so it only recomputes when query changes. Watch the console: after your fix, toggling dark mode should produce no new log.