Fix 2: split the context so the button ignores theme changes
Now toggling renders only Header, the one component that shows the theme. ToggleButton reads a context whose value (toggle) never changes. The theme string needs no useMemo: a string is compared by value.
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