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.