Back to Curriculum

State Management with Context API

📚 Lesson 7 of 18 ⏱️ 55 min

State Management with Context API

55 min

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

It's designed to share data that can be considered 'global' for a tree of React components, such as the current authenticated user, theme, or preferred language.

The `useContext` hook makes it easy to consume context values.

Context should be used sparingly - it's not a replacement for prop drilling in all cases. Overusing context can make components harder to understand and test.

When context values change, all consuming components re-render. This can cause performance issues if not managed carefully, especially with frequently changing values.

Splitting contexts by concern (e.g., separate ThemeContext and AuthContext) is better than having one large context with all global state.

Key Concepts

  • Context API enables sharing data across component tree without prop drilling.
  • createContext creates a context, Provider supplies values, useContext consumes them.
  • Context values should be relatively stable to avoid excessive re-renders.
  • Multiple contexts can be used to separate different concerns.
  • Context is ideal for truly global data like themes, authentication, and language preferences.

Learning Objectives

Master

  • Creating and providing context values
  • Consuming context with useContext hook
  • Understanding when to use context vs props
  • Optimizing context to prevent unnecessary re-renders

Develop

  • State management architecture thinking
  • Recognizing when context is appropriate
  • Understanding React's rendering optimization with context

Tips

  • Split contexts by concern rather than creating one large context.
  • Use useMemo for context values that are objects or arrays to prevent unnecessary re-renders.
  • Create custom hooks that wrap useContext for better API and error handling.
  • Consider using context for truly global state, not just to avoid prop drilling.

Common Pitfalls

  • Creating contexts for data that's only used in a few components (prop drilling is fine).
  • Not memoizing context values, causing all consumers to re-render unnecessarily.
  • Putting frequently changing values in context (use state management library instead).
  • Creating a single context with all global state instead of splitting by concern.

Summary

  • Context API shares data across component tree without prop drilling.
  • Use context for truly global state like themes and authentication.
  • Split contexts by concern to avoid unnecessary re-renders.
  • Memoize context values to optimize performance.

Exercise

Create a simple theme context to toggle between light and dark mode.

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

const ThemeContext = createContext('light');

function App() {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={theme}>
      <Toolbar />
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Toggle Theme</button>
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div>Current theme: {theme}</div>;
}

Exercise Tips

  • Create a custom useTheme hook that wraps useContext.
  • Add a default value to createContext for better error handling.
  • Consider using useMemo for the context value if it's an object.
  • Add TypeScript types for better type safety.

Code Editor

Output