easyReact Native#11

useContext theme provider

Prompt

Create a ThemeContext that provides a "dark" or "light" theme value. Build a component that consumes the context and renders its background color based on the theme.

Solution

const ThemeContext = createContext('light')
function ThemedCard() {
  const theme = useContext(ThemeContext)
  return <View style={{ backgroundColor: theme === 'dark' ? '#333' : '#fff', padding: 16 }}>
    <Text>{theme} mode</Text>
  </View>
}
// Wrap in <ThemeContext.Provider value="dark"><ThemedCard /></ThemeContext.Provider>
Mentor's take

Context solves prop drilling — threading a value through five layers of components that don't care about it — by letting any descendant read the nearest Provider's value directly. Theme is the canonical use case because it's read almost everywhere and written almost never; that read/write ratio is exactly what Context is good at.

Mechanics worth stating precisely: the argument to createContext('light') is the default, used only when a consumer has no Provider above it — it's a fallback for tests and isolated stories, not the way you set the theme. At runtime, the Provider's value wins, and every consumer re-renders when that value changes identity.

That re-render rule is the trade-off a senior names unprompted. With a string value it's harmless; the moment the value becomes an object ({ theme, toggleTheme }) created inline in the Provider's render, every consumer re-renders on every Provider render, theme change or not — memoize the value with useMemo. And keep fast-changing state (input text, scroll position) out of a broad context entirely; that's a subscription-based store's job.

Red flag: calling Context "React's state management." It's dependency injection with change notification — no selectors, no partial subscriptions; one value, all consumers re-render.

Say it: "Context is for tree-wide, rarely-changing values like theme — every consumer re-renders on value change, so I memoize object values and keep hot state in a store with selectors."