Lesson 29 +10 XP

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.


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


jsx
// 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.