Fix 1: memoise the value
The unrelated click now renders only App: the context value is the same object, so no reader is disturbed. Toggling still renders both readers, because the object really changed, and ToggleButton reads it even though it only needs toggle.
Context fits values many distant components read and that change rarely, such as the theme, the signed-in user and the locale; every reader re-renders whenever the value changes, so keep the value stable with useMemo/useCallback, split values that change at different rates into separate contexts, and don't use context for fast-changing or server data.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
This provider re-renders every reader whenever App renders: <CartContext value={{ items, add: (i) => setItems([...items, i]) }}>. Fix it with useCallback and useMemo.
Split an AuthContext that holds { user, login, logout } into a state context and an actions context, and write a LogoutButton that doesn't re-render when the user changes.
Explain it without notes
Which values are good candidates for context, and which aren't? Give examples of each.
Why does <Ctx value={{ user, logout }}> cause extra re-renders, and how do you fix it?
What does splitting a context mean and when is it worth it?
Does memo stop a component from re-rendering when a context it reads changes? Explain.
Why do state libraries with selectors render fewer components than context for the same state?
Preview
Console
Nothing logged yet.Expected console output
App rendered
Header rendered
Sidebar rendered (reads no context)
ToggleButton rendered
--- click the unrelated button
App rendered
--- click Toggle theme
App rendered
Header rendered
ToggleButton rendered