DEV Community

Cover image for React Context API Made Simple: What, Why & How I Use It in Real Projects
Manas Patil
Manas Patil

Posted on

5 2 2 2

React Context API Made Simple: What, Why & How I Use It in Real Projects

🧠 Introduction

Suppose you're working on a large project and find yourself drilling props down multiple layers of components. And every time a prop needs to be updated, you repeat the same tedious process, updating it in every intermediate component. Isn't that frustrating?

Wouldn't it be great if you could store all your useState variables and helpful functions in one central place and access them anywhere in your app with a single line of code?

That’s exactly where the React Context API comes in. It eliminates the hassle of prop drilling and allows you to manage and share related state and logic more efficiently across your application.

Prop drilling explained using diagram


❓ What Is React Context API?

If you've ever passed props through three or more components just to get them to a deeply nested child, the Context API is your rescue tool.

The React Context API provides a way to share values between components without having to pass props manually at every level. It fits well for managing global state like:

  • User authentication
  • App themes
  • Language settings
  • Firebase or API configs

Context API explained using diagram


⚙️ When (and Why) Should You Use It?

Use the Context API when you need to share state across multiple components, especially when they are deeply nested. It's great for global concerns that don’t change rapidly.

🔹 Real-world use cases:

  • Managing user authentication (login state, user data)
  • Toggling dark/light themes
  • Firebase or API configuration
  • Toasts or notifications
  • Managing related states in a modular way

⚠️ Avoid using it for frequently changing data like form inputs — it can lead to performance issues. For such cases, consider tools like Zustand, Redux, or Recoil.


🔨 Setting Up a Basic Context (Step-by-Step)

Let’s walk through setting up a UserContext for managing authentication:

Step 1: Create a contexts folder in your src directory

This helps in keeping your project organized.

Step 2: Create UserProvider.jsx

import { createContext, useState } from "react";

const UserContext = createContext(null);

const UserProvider = ({ children }) => {
  const [loggedIn, setLoggedIn] = useState(false);
  const [userCredentials, setUserCredentials] = useState({});

  const createUser = () => { /* Firebase signup logic */ };
  const getUserDetails = () => { /* Fetch user data */ };
  const updateUserDetails = () => { /* Update user */ };
  const deleteUser = () => { /* Delete user */ };

  return (
    <UserContext.Provider value={{
      loggedIn,
      createUser,
      getUserDetails,
      updateUserDetails,
      deleteUser,
      userCredentials,
      setUserCredentials
    }}>
      {children}
    </UserContext.Provider>
  );
};

export { UserContext, UserProvider };
Enter fullscreen mode Exit fullscreen mode

Step 3: Use Context in a Component

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

const Profile = () => {
  const {
    getUserDetails,
    updateUserDetails,
    userCredentials,
    setUserCredentials
  } = useContext(UserContext);

  return (
    <div>
      {/* Use the functions and state */}
    </div>
  );
};

export default Profile;
Enter fullscreen mode Exit fullscreen mode

🧩 How I Use Context in Real Projects (with Firebase)

In one of my real-world projects, ClassMantra: An AI-powered teaching assistant. I used the Context API to integrate Firebase logic.

🔗 Link to FirebaseProvider code

Here's what I used Context for:

  • User authentication and registration
  • Firestore operations: add, read, and delete assignments
  • Organizing all Firebase-related functions and state in one place for clean, reusable logic

This helped me avoid prop drilling and made Firebase access available app-wide with just one import.


⚡ Common Mistakes & Best Practices

  • Wrap your App with the Provider
import { UserProvider } from "./contexts/UserProvider";

function App() {
  return (
    <UserProvider>
      <FirebaseProvider>
        {/* Your application */}
      </FirebaseProvider>
    </UserProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Too many nested contexts (Solution: Compose or combine multiple contexts into a single provider component)
  • Using Context for fast-changing data. Frequent updates (like input values) can cause performance issues. Use local state or external state libraries for such cases.

✅ Final Thoughts

The React Context API is a powerful tool when used correctly. It simplifies global state management for things like user auth, themes, and shared logic — especially when your project scales.

Start small — try it for login state or theme toggling. Once you see how clean and manageable your app becomes, you’ll be glad you used it!


🔗 Live Demo & GitHub Repo

Live Application: ClassMantra
GitHub Repository: github.com/patilmanas04/ClassMantra

Tiugo image

Modular, Fast, and Built for Developers

CKEditor 5 gives you full control over your editing experience. A modular architecture means you get high performance, fewer re-renders and a setup that scales with your needs.

Start now

Top comments (10)

Collapse
 
nathan_tarbert profile image
Nathan Tarbert

growth like this is always nice to see - i honestly love when things get simpler after being messy for a while. you think centralizing state ever causes more confusion in big teams or does it always feel better for you?

Collapse
 
patilmanas profile image
Manas Patil • Edited

To be honest it's always a mess in big team no matter how you organize it or handle it, the thing which matter it that whose mess is less and less mess works!

Collapse
 
nevodavid profile image
Nevo David

pretty cool seeing how you made it less confusing - ever find yourself overcomplicating things before sticking with the simple route?

Collapse
 
patilmanas profile image
Manas Patil

Yes I do find myself there, then I just try to find the easy less complicated way possible.

Collapse
 
dotallio profile image
Dotallio

Love the Firebase example, it's super helpful seeing a real integration. Any quick tips on avoiding provider nesting when you've got several context providers?

Collapse
 
patilmanas profile image
Manas Patil

I already covered the common mistakes in this post and talking about tips:

  1. Nest the providers (if you have multiple providers) properly in the App.jsx only, if you have this doubt that can I wrap the other child components with providers, then my simple answer will be yes you can, you application will still work but you cannot access the context in it's parent components and this is not recommended, so wrap providers in App.jsx only.
  2. And do note this, if you have a state which changes frequently, then use Redux, using context api in such case will result in bad performance of the application. As I said in this post start small, then go big! And all set!
Collapse
 
humerah_haniyah_510 profile image
humerah haniyah

As a react developer i must say its very well explained with neat code and its very useful for beginners.

Collapse
 
patilmanas profile image
Manas Patil

I found Context API really difficult at the time I was learning react and I don't wanted any other to go through all the huge documentations and codes to learn it, so decided to make it easy for everyone with some real world examples

Collapse
 
salman_farshy_c22c8b2b8ad profile image
Salman Farsy

Context API is really helpful when we deal with lots of components.

Collapse
 
patilmanas profile image
Manas Patil

True and the best thing, everything is organized and eliminated the prop drilling

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Explore this insightful write-up embraced by the inclusive DEV Community. Tech enthusiasts of all skill levels can contribute insights and expand our shared knowledge.

Spreading a simple "thank you" uplifts creators—let them know your thoughts in the discussion below!

At DEV, collaborative learning fuels growth and forges stronger connections. If this piece resonated with you, a brief note of thanks goes a long way.

Okay