0% completed
Understanding the Context API and the useContext Hook
On This Page
The Problem Context Solves
Part 1: Creating a Context
Part 2: Providing a Value
Part 3: Reading the Value
Reading Context with use
What Context Does Not Do
Some values are needed by many components at once: the current color theme, the signed-in user, or the language of the interface. When such a value lives in a component near the top of the tree, every component between it and the reader must accept the value as a prop and pass it on, even when that component never uses it. React Fundamentals called this prop drilling.
The Context API removes those intermediate props. A component near the top provides a value, and any component below it, at any depth, can read that value directly. The value is called a context, and the component that supplies it is called a provider.
This chapter uses one running example: a small store page with a light or dark theme and, later, a shopping cart. This lesson introduces the three parts of the Context API on the theme.
The Problem Context Solves
Here is the theme passed with props. Only ThemeButton uses it, but Page and Toolbar must both accept and forward it.
function App() { const theme = 'dark'; return <Page theme={theme} />; } function Page({ theme }) { return <Toolbar theme={theme} />; } function Toolbar({ theme }) { return <ThemeButton theme={theme} />; } function ThemeButton({ theme }) { return <button className={theme}>Save</button>; }
With three levels this is manageable. With ten levels, or with five different components that need the theme in different branches, every new reader of the value means another chain of props to edit. Context lets ThemeButton ask for the theme without Page and Toolbar knowing about it.
Part 1: Creating a Context
You create a context with createContext, usually in its own file so that every component that needs it can import it.
import { createContext } from 'react'; export const ThemeContext = createContext('light');
The argument is the default value. React uses it only when a component reads the context and there is no provider anywhere above it. It is a fallback that never changes. If there is no sensible default, pass null.
Part 2: Providing a Value
A provider wraps part of the tree and gives the context a value for everything inside it. In React 19 you render the context object itself as the provider and pass a value prop:
import { ThemeContext } from './ThemeContext'; function App() { return ( <ThemeContext value="dark"> <Page /> </ThemeContext> ); }
Code written before React 19 uses <ThemeContext.Provider value="dark"> instead. That form still works in React 19 and does exactly the same thing, so you will meet it often in existing projects. New code can use the shorter form.
The prop must be named value. A provider with no value prop gives its children undefined, not the default value, and React prints a warning. This is what our run printed for <ThemeContext><Label /></ThemeContext>:
The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it? provider with no value prop: "theme is "
Part 3: Reading the Value
A component reads the nearest provider's value with the useContext hook. Page and Toolbar no longer mention the theme at all:
import { useContext } from 'react'; import { ThemeContext } from './ThemeContext'; function Page() { return <Toolbar />; } function Toolbar() { return <ThemeButton />; } function ThemeButton() { const theme = useContext(ThemeContext); return <button className={theme}>Save</button>; }
The diagram shows the same tree with the value moving from the provider straight to the component that reads it.
Notice that Page and Toolbar sit inside the provider but take no part in delivering the value. React looks upward from ThemeButton to the closest ThemeContext provider and returns its value.
"Closest" matters when providers are nested. An inner provider overrides an outer one for its own subtree, which lets one section of a page use a different theme:
<ThemeContext value="dark"> <Label /> <ThemeContext value="blue"> <Label /> </ThemeContext> </ThemeContext>
nested: [ 'theme is dark', 'theme is blue' ]
The first Label sees "dark" and the second sees "blue". A Label rendered with no provider above it at all would see the default, "light".
Reading Context with use
React 19 added a second way to read a context, the use function. For context, use(ThemeContext) returns the same value as useContext(ThemeContext). The difference is where you may call it. Hooks such as useContext must be called at the top level of a component, but use may be called inside an if statement or a loop:
import { use } from 'react'; import { ThemeContext } from './ThemeContext'; function Banner({ show }) { if (!show) { return null; } const theme = use(ThemeContext); return <p className={theme}>Free shipping this week</p>; }
When show is false, the component returns early and never reads the context. With useContext, that early return before the hook call would break the rules of hooks. Like a hook, use must still be called inside a component or a custom hook, and it cannot be placed inside a try block.
Most code you read will use useContext, and it remains the usual choice when the value is needed on every render. This course uses useContext in its examples.
What Context Does Not Do
Context only delivers a value. It does not store state, and it does not decide when the value changes. In the examples so far the value is a fixed string, so nothing on the screen can change it.
To make the theme changeable, the value must come from state that some component owns, usually with useState or useReducer in the component that renders the provider. Context then delivers the current state, and React re-renders the components that read it whenever that state changes.
You may also see a third reading method, <ThemeContext.Consumer>, which takes a function as its child. It is the form that existed before hooks. It still works, but new code should use useContext or use.
Reading Progress
0%
On This Page
The Problem Context Solves
Part 1: Creating a Context
Part 2: Providing a Value
Part 3: Reading the Value
Reading Context with use
What Context Does Not Do