Hands-on practice for this lecture. Work through the exercises and quizzes to reinforce what you've learned.
Exercise 1 of 2
Three useCallback scenarios — when it prevents re-renders, when missing deps cause stale callbacks, and when it is useless overhead.
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('clicked');
}, []); // empty deps
return (
<>
<button onClick={() => setCount(c => c + 1)}>+1</button>
<MemoChild onClick={handleClick} />
</>
);
}
const MemoChild = React.memo(Child);Does MemoChild re-render when count changes?
function Parent({ userId }) {
const loadUser = useCallback(() => {
fetchUser(userId);
}, []); // userId missing from deps
useEffect(() => {
loadUser();
}, [loadUser]);
}What bug does the empty dep array introduce?
function SimpleButton({ label, onClick }) {
return (
<button
onClick={useCallback(onClick, [onClick])}
>
{label}
</button>
);
}Is this useCallback useful?
0/3 answered
💡 useCallback is only useful in two places: passing stable callbacks to React.memo components, and stabilizing functions used as effect dependencies. Everywhere else it adds overhead without benefit.
Exercise 2 of 2
Live editor: memoized ProductCards re-render on every search keystroke. Wrap the handler in useCallback so memo can do its job.
Task
Open the console and type in the search box. Every keystroke re-renders all ProductCard components — even though the cart logic has not changed. The cards are wrapped in memo but it is not helping.
Wrap handleAddToCart in useCallback with an appropriate dep array. After the fix, typing in search should not cause the cards to re-render (check the console).