Context API

Introduction

Context passes data through the component tree without manual prop drilling at every level. Use it for theme, locale, or lightweight auth—not as a replacement for all global state. This chapter covers createContext, Provider, useContext, and performance pitfalls.

Prerequisites

Basic Context

ThemeContext.tsx:

Wrap the app in main.tsx:

tsx
createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <ThemeProvider>
      <App />
    </ThemeProvider>
  </StrictMode>
);

Consumer:

tsx
function ThemeToggle() {
  const { theme, toggleTheme } = useTheme();
  return (
    <button type="button" onClick={toggleTheme}>
      Current: {theme}
    </button>
  );
}

Code explanation:

  • Provider supplies value to all descendants
  • Custom hook useTheme validates provider presence
  • Compare Vue provide / injectVue chapter 12

Default Context Value

tsx
const LocaleContext = createContext("en");

Without a Provider, consumers read the default. For required context, use undefined default + guard in useXxx hook.

Auth Context (Simple)

For JWT apps with many actions, prefer Zustandchapter 15 and admin project.

Performance: Split Contexts

One big context object causes all consumers to re-render when any field changes.

PatternBenefit
ThemeContext + AuthContextIsolated updates
Memoize value with useMemoStable reference when deps unchanged
Zustand selectorsSubscribe to slices
tsx
const value = useMemo(
  () => ({ theme, toggleTheme }),
  [theme]
);
 
return (
  <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
);

Context vs Zustand vs Props

ToolBest for
PropsParent → child, 1–2 levels
ContextTheme, i18n, compound components
ZustandTodo list, cart, auth token used everywhere

FAQ

useContext outside Provider?

Returns default or undefined—guard in custom hook.

Multiple providers?

Nest them:

tsx
<AuthProvider>
  <ThemeProvider>
    <App />
  </ThemeProvider>
</AuthProvider>

Context + TypeScript?

Export useTheme with thrown error for missing provider—best DX.

Replace Redux with Context?

Small apps yes; frequent updates or middleware → Zustand/Redux.

Next chapter?

Custom Hooks.