← Back to Chapters

React Context API

⚛️ React Context API

? Quick Overview

The Context API in React provides a way to share data across the component tree without passing props manually through every nested level.

It is perfect for global data such as:

  • Theme (light / dark)
  • User authentication / session
  • Language / localization
  • App-wide user preferences

? No More Prop Drilling   ? Global State Sharing

? Key Concepts in Context API

The Context API mainly revolves around three core steps:

  1. Create a context using React.createContext()
  2. Provide a value using the Provider component
  3. Consume that value using useContext() or Context.Consumer

Important pieces:

  • createContext() → Creates a new context object.
  • Provider → Makes a value available to all children.
  • useContext() → Reads the current context value.
  • Consumer → Older way to use context (render prop pattern).

? Syntax & Theory

Basic pattern when working with Context API in a React app:

1️⃣ Creating a Context

? View Code Example
// Create a context with an optional default value
import React from "react";

export const MyContext = React.createContext("defaultValue");

2️⃣ Providing Context Value

? View Code Example
// Wrap part of your tree with the Provider
import React from "react";
import { MyContext } from "./MyContext";
import SomeChild from "./SomeChild";

function App() {
  const sharedValue = "Hello from Context!";

  return (
    <MyContext.Provider value={sharedValue}>
      <SomeChild />
    </MyContext.Provider>
  );
}

export default App;

3️⃣ Consuming Context with useContext

? View Code Example
// Read the nearest context value with useContext
import React, { useContext } from "react";
import { MyContext } from "./MyContext";

function SomeChild() {
  const value = useContext(MyContext);

  return <p>Current value: {value}</p>;
}

export default SomeChild;

✨ useContext = Fast Access to Context Data

? Example 1: Theme Context (Light / Dark)

In this example, we use the Context API to store and toggle the app’s theme between "light" and "dark".

Step 1: Create ThemeContext

? View Code Example
// ThemeContext.js - defines a context for theme state
import React from "react";

export const ThemeContext = React.createContext("light");

Step 2: Provide Theme Value in App

? View Code Example
// App.js - wraps children with ThemeContext.Provider
import React, { useState } from "react";
import { ThemeContext } from "./ThemeContext";
import Toolbar from "./Toolbar";

function App() {
  const [theme, setTheme] = useState("light");

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

export default App;

Step 3: Consume Theme in Toolbar

? View Code Example
// Toolbar.js - uses useContext to read & update theme
import React, { useContext } from "react";
import { ThemeContext } from "./ThemeContext";

function Toolbar() {
  const { theme, setTheme } = useContext(ThemeContext);

  return (
    <div
      className={`p-3 text-center bg-${
        theme === "light" ? "light" : "dark"
      } text-${theme === "light" ? "dark" : "light"}`}
    >
      <p>Current Theme: {theme}</p>
      <button
        className="btn btn-primary"
        onClick={() => setTheme(theme === "light" ? "dark" : "light")}
      >
        Toggle Theme
      </button>
    </div>
  );
}

export default Toolbar;

?️ Live Output / Explanation

  • The app starts in light theme (default value: "light").
  • Toolbar reads theme and setTheme from ThemeContext.
  • When the user clicks Toggle Theme, the theme value flips between light and dark.
  • All components using this context automatically re-render when the theme changes.

? Example 2: User Authentication Context

Here, the Context API is used to manage login state and functions like login() and logout() globally.

Step 1: Create AuthContext & Provider

? View Code Example
// AuthContext.js - manages global authentication state
import React, { createContext, useState } from "react";

export const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  const login = (username) => setUser({ name: username });
  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

Step 2: Wrap App with AuthProvider

? View Code Example
// App.js - provides auth context to the whole app
import React from "react";
import { AuthProvider } from "./AuthContext";
import Dashboard from "./Dashboard";

function App() {
  return (
    <AuthProvider>
      <Dashboard />
    </AuthProvider>
  );
}

export default App;

Step 3: Use AuthContext in Dashboard

? View Code Example
// Dashboard.js - consumes auth state & actions
import React, { useContext } from "react";
import { AuthContext } from "./AuthContext";

function Dashboard() {
  const { user, login, logout } = useContext(AuthContext);

  return (
    <div className="text-center">
      {user ? (
        <>
          <h4>Welcome, {user.name}!</h4>
          <button className="btn btn-danger" onClick={logout}>
            Logout
          </button>
        </>
      ) : (
        <button
          className="btn btn-success"
          onClick={() => login("Meghraj")}
        >
          Login
        </button>
      )}
    </div>
  );
}

export default Dashboard;

?️ Live Output / Explanation

  • Initially, user is null, so the Login button is shown.
  • On clicking Login, login("Meghraj") sets a user object in context.
  • The UI updates and shows Welcome, Meghraj! with a Logout button.
  • Any component in the tree can access user, login and logout without prop drilling.

? useContext Hook

The useContext() hook is the most common and cleaner way to consume context data in modern React applications.

? View Code Example
// Simple pattern to read context value
import React, { useContext } from "react";
import { MyContext } from "./MyContext";

function MyComponent() {
  const value = useContext(MyContext);

  return <p>Context value: {value}</p>;
}

useContext(MyContext) always returns the nearest <MyContext.Provider> value above it in the component tree.

? Context API Summary

Concept Description
createContext() Creates a new Context object.
Provider Supplies the context value to all its children.
useContext() Hook that lets components consume context easily.
Consumer Older render-prop API (less common now).

? Tips & Best Practices

  • Keep context data small and focused — avoid huge objects or rapidly changing values.
  • Split large contexts (e.g., user, theme, settings) into multiple smaller contexts for better performance.
  • Combine Context API with useReducer for more complex or scalable state management.
  • Use context only for truly shared global data, not for every single prop.
  • For very large apps, consider libraries like Redux, Zustand, etc., with context under the hood.

? Try It Yourself / Practice Tasks

  1. Create a LanguageContext that toggles between English and Hindi and displays text in the chosen language.
  2. Build a ThemeContext that stores "dark" or "light" and toggles theme using a button.
  3. Implement a UserContext that tracks login status and shows the current user’s name in a navbar.
  4. Experiment with multiple nested providers (e.g., AuthContext + ThemeContext + LanguageContext).

Goal: Understand how the Context API simplifies data sharing across components, removes prop drilling, and improves scalability in medium-to-large React applications.