The Context API
Share values across the tree with a Provider and consumers.
Syntax
<MyContext.Provider value={data}>...</MyContext.Provider>The Context API shares data across many components without passing props at each level. A Provider supplies a value; any descendant can read it with useContext.
When to reach for it
Great for app-wide data like the current theme, language, or logged-in user. When the Provider's value changes, every consumer re-renders with the new value.
Example
import { createContext, useContext, useState } from 'react';
const UserContext = createContext(null);
function useUser() {
return useContext(UserContext);
}
function Greeting() {
const user = useUser();
return <p>Hi, {user.name}</p>;
}
function App() {
const [user] = useState({ name: 'Ada' });
return (
<UserContext.Provider value={user}>
<Greeting />
</UserContext.Provider>
);
}When to use it
- A multi-language app wraps the component tree in a LocaleProvider so any component can call useContext(LocaleContext) to get translated strings without prop drilling.
- A colour-scheme toggle stores the active theme in a context so the Header, Sidebar, and every Button component reads the same value from one provider.
- An analytics library injects a tracking instance through context so child components can log events without receiving the tracker as an explicit prop.
More examples
Create context and provider
Creates a context, a provider that supplies current locale and a setter, and a convenience hook for consumers.
import { createContext, useState, useContext } from 'react';
const LocaleContext = createContext('en');
export function LocaleProvider({ children }) {
const [locale, setLocale] = useState('en');
return (
<LocaleContext.Provider value={{ locale, setLocale }}>
{children}
</LocaleContext.Provider>
);
}
export const useLocale = () => useContext(LocaleContext);Consume context in a child
Reads the current locale from context with the custom hook and looks up the matching translation.
import { useLocale } from './LocaleProvider';
const messages = {
en: { greeting: 'Hello' },
es: { greeting: 'Hola' },
};
function Greeting() {
const { locale } = useLocale();
return <h1>{messages[locale].greeting}!</h1>;
}Update context from any depth
Updates the context value from a deeply nested component by calling the setter provided through context.
import { useLocale } from './LocaleProvider';
function LocaleSwitcher() {
const { locale, setLocale } = useLocale();
return (
<select value={locale} onChange={e => setLocale(e.target.value)}>
<option value="en">English</option>
<option value="es">EspaΓ±ol</option>
</select>
);
}
Discussion