Part 20: useContext Hook: Global Data Without Prop Drilling

Part 20 Technology Updated September 12, 2026

Part 20: useContext Hook: Global Data Without Prop Drilling

Prop drilling occurs when you need to pass data through multiple layers of intermediate components that don't need the data themselves, just to reach a deeply nested child.


1. The Context Solution

React's Context API provides a way to share values (like authentication state, theme, or localization) across the entire component tree without explicitly passing props through every level.

       [ ThemeContext.Provider value="dark" ]
                         │
                  [ App Component ]
                         │
                 [ DashboardPage ]
                         │
                 [ SettingsCard ]
                         │
      [ DarkModeToggle (Consumes ThemeContext) ]

2. Creating and Providing Context

Step 1: Create Context and Provider (ThemeContext.jsx):

import { createContext, useState, useContext } from 'react';

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

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

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      <div className={theme === 'dark' ? 'bg-gray-900 text-white min-h-screen' : 'bg-white text-black min-h-screen'}>
        {children}
      </div>
    </ThemeContext.Provider>
  );
}

// Custom hook for convenient consumption:
export function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }
  return context;
}

Step 2: Wrap Root Component:

import { ThemeProvider } from './ThemeContext';
import MainDashboard from './MainDashboard';

export default function App() {
  return (
    <ThemeProvider>
      <MainDashboard />
    </ThemeProvider>
  );
}

Step 3: Consume Deep in the Tree:

import { useTheme } from './ThemeContext';

export default function ThemeToggleBtn() {
  const { theme, toggleTheme } = useTheme();

  return (
    <button onClick={toggleTheme} className="btn-toggle">
      Active Theme: {theme.toUpperCase()} (Click to toggle)
    </button>
  );
}

Key Takeaways

  • Use Context to avoid prop drilling for widely consumed data (auth, themes, translations).
  • Create custom hooks (useTheme()) to encapsulate context consumption safely.
  • Keep contexts focused on specific domains to avoid unnecessary re-renders.

In Part 21, we explore complex state machines with the useReducer Hook!