The Codex / Technologies / React / Context API

Context API

Sharing data across many components without passing props through every level - createContext, Provider, and useContext explained.

What it is, in plain English: Context lets a component tree share data without passing it down manually through every intermediate component (avoiding 'props drilling'). You create a Context with createContext(), wrap part of the tree in a Provider that supplies a value, and any descendant component can read that value with useContext() -- no matter how deeply nested. Context is best for data that many components need: theme, current user, language, or app-wide settings.

Avoiding props drilling

If many components need the same piece of data -- the current theme, the logged-in user, the selected language -- passing it down as a prop through every layer ("props drilling") gets tedious and brittle. Context lets distant descendants read a value directly, skipping all the layers in between.

The three steps

// STEP 1: Create the context (usually in its own file)
const ThemeContext = React.createContext("light");  // "light" = default value

// STEP 2: Wrap part of your tree in a Provider, supplying the actual value
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Page />
    </ThemeContext.Provider>
  );
}

// STEP 3: Read the value anywhere inside, with useContext
function DeeplyNestedButton() {
  const theme = React.useContext(ThemeContext);
  return <button className={theme}>Click</button>;
}
// DeeplyNestedButton can be 10 levels deep -- it still reads "dark" directly,
// with NO props passed through any of the components in between.

Context with state -- the common real pattern

function App() {
  const [theme, setTheme] = React.useState("light");

  return (
    <ThemeContext.Provider value={theme}>
      <button onClick={() => setTheme("dark")}>Switch to dark</button>
      <Dashboard />
    </ThemeContext.Provider>
  );
}

// When theme state changes, EVERY component reading ThemeContext re-renders
// automatically with the new value -- no manual prop updates needed anywhere.

Without Context vs with Context

// ✗ WITHOUT Context -- props drilling through layers that don't use the data:
function App()      { return <Layout user={user} />; }
function Layout({ user })   { return <Sidebar user={user} />; }
function Sidebar({ user })  { return <UserMenu user={user} />; }
function UserMenu({ user }) { return <p>{user.name}</p>; }

// ✓ WITH Context -- only the component that needs it touches it:
const UserContext = React.createContext(null);
function App()    { return <UserContext.Provider value={user}><Layout /></UserContext.Provider>; }
function Layout()   { return <Sidebar />; }      // no 'user' prop needed
function Sidebar()  { return <UserMenu />; }     // no 'user' prop needed
function UserMenu()  {
  const user = React.useContext(UserContext);    // reads directly
  return <p>{user.name}</p>;
}
Try It Yourself (JSX)

Official Sources

The Codex links only to official documentation. No third-party tutorials.