DEV Community

Cover image for How to Use React Context API for State Management (Without Prop Drilling)
Anshi
Anshi

Posted on

How to Use React Context API for State Management (Without Prop Drilling)

Managing state in React can be tricky especially when you have deeply nested components and lots of props to pass down. The React Context API is a built-in solution that lets you share state globally (or within certain component trees) so you avoid “prop drilling.” In this guide, we’ll walk through how to set it up, when to use it, and when you might still want a more powerful state library.


🧠 Why Use Context API?

In many React apps, you’ll find yourself passing props through layers of components just so a child way down the tree gets access. That’s prop drilling - tedious and error-prone.

Context API helps you:

  • Expose data at a higher level so many components can consume it directly
  • Avoid passing props through intermediate components
  • Make state like theme, authentication, language, or user settings accessible app-wide

That said, for complex state logic (with many updates, derived state, or performance concerns), context alone might start to feel limiting. It’s great for moderate use cases.


How to Use React Context API (Step by Step)

Here’s how you can set up and use context in your React app.

1. Create a Context

Create a file, e.g. AuthContext.js:

import { createContext } from "react";

const AuthContext = createContext({
  user: null,
  setUser: () => {},
});

export default AuthContext;
Enter fullscreen mode Exit fullscreen mode

This gives you a context object with default values.

2. Provide the Context

Wrap part of your app (often at top-level) with a Provider so children can consume its state:

import AuthContext from "./AuthContext";
import { useState } from "react";

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

  const value = { user, setUser };

  return (
    <AuthContext.Provider value={value}>
      {children}
    </AuthContext.Provider>
  );
}

export default AuthProvider;
Enter fullscreen mode Exit fullscreen mode

Use AuthProvider above your component tree:

function App() {
  return (
    <AuthProvider>
      <MainApp />
    </AuthProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

3. Consume the Context

In any child component:

import { useContext } from "react";
import AuthContext from "./AuthContext";

function Profile() {
  const { user, setUser } = useContext(AuthContext);

  return (
    <div>
      {user ? <p>Welcome, {user.name}</p> : <p>Please log in</p>}
      <button onClick={() => setUser({ name: "Alice" })}>
        Log In as Alice
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

You can also use the Context Consumer pattern or combine with useReducer for more structured logic.


When (and When Not) to Use Context API

Use Case Good for Context Better Alternatives
Theme, locale, authentication ✅ Yes
Global UI state (modals, menus) ✅ Manageable
Complex state with many updates ⚠️ May cause re-render performance issues Zustand, Redux, Jotai, Recoil
Pagination / forms / caching logic ❌ Better with specialized libraries or custom hooks Use context + hooks or external state libs

Final Thoughts

React Context API is a powerful tool in your toolkit. It’s lightweight, built into React, and perfect for many moderate cases of shared state. But always keep performance and complexity in mind: for large-scale apps, combining context with other patterns or libraries often gives you the best balance.

Let talks to know how to integrate context with AI/Automation workflows!

Top comments (0)