A hands-on learning project to understand React Context API and solve the prop drilling problem.
By completing this assignment, you will:
- Understand what prop drilling is and why it's a problem
- Learn how to use React's Context API to share state across components
- Practice creating Context Providers and consuming them with useContext
- Experience the difference between prop drilling and context-based state management
-
Install dependencies:
npm install
-
Run the development server:
npm run dev
-
Open the app: Navigate to http://localhost:3000
This app currently works perfectly! It has:
- Theme toggling (light/dark mode)
- Language switching (English/Spanish/French)
However, look at how the code is structured:
app/page.tsx (holds state)
↓ props
components/Layout.tsx (passes props through)
↓ props
components/Header.tsx (uses language)
components/Content.tsx (passes props through)
↓ props
components/SettingsPanel.tsx (uses all props)
components/Footer.tsx (uses theme & language)
Notice that Layout and Content components receive props they don't even use! They only pass them down to children. This is called prop drilling.
The project is already configured with Tailwind CSS v4. In app/globals.css, the dark mode variant is configured to use class-based toggling:
@variant dark (&:where(.dark, .dark *));This allows your app to control dark mode via state instead of system preferences.
- Create a new file:
context/ThemeContext.tsx - Create a
ThemeContextusingcreateContext - Create a
ThemeProvidercomponent that:- Manages theme state (
'light'or'dark') - Provides the theme value and setter function
- Manages theme state (
- Export a custom hook
useThemefor easy consumption
- Create a new file:
context/LanguageContext.tsx - Create a
LanguageContextusingcreateContext - Create a
LanguageProvidercomponent that:- Manages language state (
'en','es', or'fr') - Provides the language value and setter function
- Manages language state (
- Export a custom hook
useLanguagefor easy consumption
- Update
app/layout.tsxto wrap the app with both providers - Make sure to mark the layout as
'use client'since Context requires client-side rendering
Update these components to use your new context hooks:
- app/page.tsx - Remove state management (now in Context)
- components/Layout.tsx - Remove all props, add
useEffectto apply dark class to html element - components/Header.tsx - Use
useLanguage()instead of props - components/Content.tsx - Remove all props
- components/SettingsPanel.tsx - Use
useTheme()anduseLanguage()instead of props - components/Footer.tsx - Use
useTheme()anduseLanguage()instead of props
Important: In Layout.tsx, you'll need to use useEffect to apply/remove the dark class to document.documentElement based on the theme state. This makes Tailwind's dark: classes work with your app state instead of system preferences.
- Remove all unnecessary prop types
- Delete TODO comments once you've addressed them
- Test that theme and language switching still works!
If you finish early or want to deepen your understanding:
- Combine Contexts: Create a single
AppContextthat manages both theme and language - Persist State: Use
localStorageto remember the user's theme and language preferences - Add More Features: Add a new piece of global state (e.g., username, notification settings)
- TypeScript Refinement: Make the context types more robust with proper TypeScript patterns
After completing this assignment:
- No more prop drilling through intermediate components
- Cleaner component props (only what they actually need)
- Theme and language are accessible anywhere in the component tree
- The app still functions exactly the same way!
This project includes several resources to guide you:
HINTS.md- Progressive hints for each task if you get stuckSOLUTION.md- Complete working solution with detailed explanationsWHY-CONTEXT.md- Deep dive into why Context exists and when to use it- Code comments - Look for
// TODO:and// TASK:comments in the code
Recommended approach:
- Try to solve each task on your own first
- If stuck, check HINTS.md for guidance
- Only look at SOLUTION.md after completing or if completely blocked
- Read WHY-CONTEXT.md to understand the deeper concepts
Good luck! 🚀