JSTAcademy
0 XP
Dashboard
Crash Courses
Context & Prop Drilling
11 min
Masters+175 XP
Crash Courses · Masters

Context & Prop Drilling

Share state across deep component trees without prop drilling using React Context.
11 min read+175 XP on completionCert: React Crash Course
Tap any word in the text below to start reading from there.

Context & Prop Drilling

Context lets you share state across a component tree without passing props manually through every level.

Creating Context

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

interface ThemeContextValue {
  theme: 'light' | 'dark'
  toggleTheme: () => void
}

const ThemeContext = createContext<ThemeContextValue | null>(null)

export function ThemeProvider({ children }: { children: React.ReactNode }) {
  const [theme, setTheme] = useState<'light' | 'dark'>('light')

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

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  )
}

export function useTheme() {
  const ctx = useContext(ThemeContext)
  if (!ctx) throw new Error('useTheme must be inside ThemeProvider')
  return ctx
}

Consuming Context

// Deep in the tree — no prop drilling needed
function ThemeToggle() {
  const { theme, toggleTheme } = useTheme()
  return (
    <button onClick={toggleTheme}>
      {theme === 'light' ? 'Switch to Dark' : 'Switch to Light'}
    </button>
  )
}

Course Progress Context Pattern

interface ProgressContextValue {
  completed: Set<string>
  markComplete: (courseId: string) => void
  isComplete: (courseId: string) => boolean
}

const ProgressContext = createContext<ProgressContextValue | null>(null)

export function ProgressProvider({ children }: { children: React.ReactNode }) {
  const [completed, setCompleted] = useState<Set<string>>(new Set())

  const markComplete = (id: string) =>
    setCompleted(prev => new Set([...prev, id]))

  const isComplete = (id: string) => completed.has(id)

  return (
    <ProgressContext.Provider value={{ completed, markComplete, isComplete }}>
      {children}
    </ProgressContext.Provider>
  )
}

When to Use Context vs Props

Use context for: theme, current user, language/locale, global notifications.

Use props for: component-specific data, data that only flows one level down.

0%