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.

A Context Provider at the top supplies a value that flows to consumer components at any depth without passing through the middle layersProvider (value)LayoutConsumerOtherConsumer
The value skips intermediate components and reaches consumers directly via useContext.

Example

Example · javascript
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.

Example · jsx
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.

Example · jsx
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.

Example · jsx
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

  • Be the first to comment on this lesson.