How to Consume Context with useContext Hook in React (Step-by-Step Guide)

After creating and providing Context in React, the next step is to consume it inside components.

React gives us an easy way to do this using the useContext Hook — it allows functional components to directly access context data without needing to pass props manually.

Think of it like this:

The Provider broadcasts data, and the useContext Hook tunes in to that data.

What is useContext?

The useContext Hook lets you read and use the current context value directly inside a functional component.

Syntax:

 
const value = useContext(MyContext);
  • MyContext → The context object created using createContext().

  • value → The data that you provided through <MyContext.Provider>.

Example 1: Basic Context Consumption

Step 1: Create a Context

 
import { createContext } from "react";
export const UserContext = createContext();

Step 2: Provide Context

import React from "react";
import { UserContext } from "./UserContext";
import Profile from "./Profile";

function App() {
  const user = { name: "John Doe", age: 28 };

  return (
    <UserContext.Provider value={user}>
      <Profile />
    </UserContext.Provider>
  );
}

export default App;

Step 3: Consume Context with useContext

import React, { useContext } from "react";
import { UserContext } from "./UserContext";

function Profile() {
  const user = useContext(UserContext);

  return (
    <div>
      <h2>User Profile</h2>
      <p>Name: {user.name}</p>
      <p>Age: {user.age}</p>
    </div>
  );
}

export default Profile;

Output:

 
User Profile
Name: John Doe
Age: 28

Example 2: Consuming Functions from Context

You can also pass functions inside Context and use them from anywhere in your app.

 
// ThemeContext.js import { createContext } from "react";
export const ThemeContext = createContext();
// App.js
import React, { useState } from "react";
import { ThemeContext } from "./ThemeContext";
import ThemeSwitcher from "./ThemeSwitcher";

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

  const toggleTheme = () =>
    setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));

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

export default App;
// ThemeSwitcher.js
import React, { useContext } from "react";
import { ThemeContext } from "./ThemeContext";

function ThemeSwitcher() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <div
      style={{
        backgroundColor: theme === "light" ? "#f5f5f5" : "#333",
        color: theme === "light" ? "#000" : "#fff",
        padding: "20px",
      }}
    >
      <h3>Current Theme: {theme}</h3>
      <button onClick={toggleTheme}>Switch Theme</button>
    </div>
  );
}

export default ThemeSwitcher;

What Happens Here:

  • App provides the theme and toggle function.

  • ThemeSwitcher consumes them using useContext.

  • You can toggle the theme without passing props through multiple components.

How useContext Works

Here’s the flow:

  1. Create Contextconst MyContext = createContext()

  2. Provide Context<MyContext.Provider value={data}>

  3. Consume Contextconst data = useContext(MyContext)

Visualization:

 
App
└── MyContext.Provider (value = {user})
        └── Dashboard
                └── Profile → useContext(MyContext)

The Profile component can directly access user even though it’s nested multiple levels deep.

Best Practices

 Do’s Don’ts
Use one context per concern (e.g., Theme, Auth, Language).Don’t put everything in one context.
Combine useContext with useState or useReducer for dynamic updates.Don’t mutate context values directly.
Wrap the entire app in a provider (usually in App.js or index.js).Don’t forget to wrap the consumer inside the Provider.
Use custom hooks to simplify context usage.Don’t use useContext outside a Provider.

Example 3: Custom Hook for Context

Instead of writing useContext(ThemeContext) everywhere, create a custom hook for cleaner access.

 
// useTheme.js
import { useContext } from "react";
import { ThemeContext } from "./ThemeContext";
export function useTheme() {
return useContext(ThemeContext);
}

Now use it like this:

import React from "react";
import { useTheme } from "./useTheme";

function Navbar() {
  const { theme, toggleTheme } = useTheme();

  return (
    <nav style={{ background: theme === "light" ? "#eee" : "#222" }}>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </nav>
  );
}

export default Navbar;

Cleaner, reusable, and easier to maintain.