# Context — React

Source: https://www.skillbyai.com/en/react/h-context

> Data available to a whole subtree.

## Provider above, useContext below

**Context** lets a parent make a value available to every component below it without passing props through each layer (**prop drilling**). Create it with `createContext(default)`, provide a value higher in the tree (in React 19 you can render `<MyContext value={...}>` directly; earlier versions use `<MyContext.Provider>`), and read it with `useContext`. Good uses: theme, current user, locale. Avoid putting rapidly changing values in a widely used context, since every consumer re-renders when it changes.

## Context, custom hooks and refs

Avoid prop drilling with context, reuse stateful logic with custom hooks, and reach the DOM with refs.

![Three ideas: context, custom hooks, refs.](assets/figures/react/section-6-map.svg) — Figure 6.1 — Context, custom hooks and refs.

## A theme without prop drilling, run

I ran this with React 19.3 and react-dom 19.3 on Node.js 22, compiling JSX with esbuild 0.28. Browser-style examples use jsdom 29 as a fake DOM (imported from a small setup-dom.mjs file) and act() to apply updates. Without a provider, the button uses the default "light" theme; wrapped in a dark provider, the same Toolbar renders a "btn-dark" button, even though Toolbar never passes a theme prop.

```jsx
import { createContext, useContext } from "react";
import { renderToStaticMarkup } from "react-dom/server";

const ThemeContext = createContext("light");          // default when no provider is above
function Button({ children }) {
  const theme = useContext(ThemeContext);
  return <button className={`btn-${theme}`}>{children}</button>;
}
function Toolbar() { return <div><Button>Save</Button></div>; }   // no theme prop passed through
console.log(renderToStaticMarkup(<Toolbar />));
console.log(renderToStaticMarkup(<ThemeContext value="dark"><Toolbar /></ThemeContext>));
```

Output:

```
<div><button class="btn-light">Save</button></div>
<div><button class="btn-dark">Save</button></div>
```

## Split contexts by change frequency

Keep slow-changing values (theme, user) separate from fast-changing ones to limit re-renders.

**Quiz:** What problem does context solve?

- [ ] Styling components
- [ ] Fetching data from APIs
- [x] Passing data through many intermediate components (prop drilling)
- [ ] Speeding up every render

*Answer:* Passing data through many intermediate components (prop drilling). Share values with a subtree.
