Lesson 29 +10 XP

Context Provider

Context Provider

Creating a context object with createContext() is only the first step. To supply dynamic values to descendant components, you must wrap your component tree in a Context Provider.

The <Context.Provider> Component

Every Context object comes with a built-in React component named Provider. The Provider accepts a value prop which holds the data you want to make available to all child components inside that subtree.

import { useState } from 'react';
import { ThemeContext } from './ThemeContext';

function App() {
  const [theme, setTheme] = useState('dark');

  const toggleTheme = () => {
    setTheme(prev => (prev === 'light' ? 'dark' : 'light'));
  };

  return (
    // Wrap descendant tree in Provider and pass value object
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      <div className={"app-container " + theme}>
        <Header />
        <MainContent />
      </div>
    </ThemeContext.Provider>
  );
}

How Value Prop Updates Work

Whenever the value prop passed to a <Context.Provider> changes (for example, when theme state updates from 'light' to 'dark'), all descendant components subscribing to that context automatically re-render with the new value.

Custom Provider Wrappers Pattern

In professional codebases, developers create custom Context Provider components that package both the Provider element and its state management logic together.

// src/context/AuthContext.jsx
import { createContext, useState } from 'react';

export const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  const login = (userData) => setUser(userData);
  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

Summary & TL;DR

  • <Context.Provider value={data}> provides context values to all child elements wrapped inside it.
  • Descendants can read context data regardless of how deeply nested they are.
  • When the value prop updates, all consumer components automatically re-render.
  • Packaging provider components with state logic into custom Providers keeps App.jsx clean.