Ojasa Mirai

Ojasa Mirai

ReactJS

Loading...

Learning Level

🟒 BeginnerπŸ”΅ Advanced
🌍 Context API BasicsπŸ“¦ Creating ContextπŸ”Œ Context.ProviderπŸ” useContext Hook🎯 Passing Data with ContextπŸ”„ Context with useState⚑ Context PerformanceπŸ—οΈ Context Best Practices
Reactjs/Context/Context Api Basics

🌍 Context API Basics β€” Solving Prop Drilling

Prop drilling happens when you pass data through many levels of components that don't need it, just to reach a component that does. Context lets you share data directly without passing it through every level.


🎯 The Prop Drilling Problem

Imagine you have a user logged in at the top of your app, and a component deep in the tree needs to display their name. Without Context, you'd pass the user through every component in between:

// Without Context: props drilling through every level
function App() {
  const [user, setUser] = useState({ name: "Alice" });
  return <Nav user={user} />;
}

function Nav({ user }) {
  return <Header user={user} />;
}

function Header({ user }) {
  return <UserInfo user={user} />;
}

function UserInfo({ user }) {
  return <h1>Welcome, {user.name}!</h1>;
}

This works, but it's cumbersome. The Nav and Header components don't care about the userβ€”they're just passing it along. If you have 10 levels of nesting, this becomes tedious and hard to maintain.

πŸ’‘ What is Context?

Context lets you skip the middle components. You create a Context, put data into it at the top level, and any component inside can access it directlyβ€”no matter how deep.

// With Context: direct access without drilling
import { createContext, useContext, useState } from "react";

const UserContext = createContext();

function App() {
  const [user, setUser] = useState({ name: "Alice" });
  return (
    <UserContext.Provider value={user}>
      <Nav />
    </UserContext.Provider>
  );
}

function Nav() {
  return <Header />;
}

function Header() {
  return <UserInfo />;
}

function UserInfo() {
  const user = useContext(UserContext);
  return <h1>Welcome, {user.name}!</h1>;
}

Notice: Nav and Header don't receive user as a prop. UserInfo accesses it directly from Context.

<details>

<summary>πŸ“š More Examples</summary>

// Example 2: Theme context - switching between light and dark mode
import { createContext, useContext, useState } from "react";

const ThemeContext = createContext();

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

  return (
    <ThemeContext.Provider value={theme}>
      <Page />
    </ThemeContext.Provider>
  );
}

function Page() {
  return <Content />;
}

function Content() {
  const theme = useContext(ThemeContext);
  const bgColor = theme === "light" ? "white" : "black";
  return <div style={{ background: bgColor }}>Content here</div>;
}

</details>

🎨 Real-World Example: Authentication Context

Many apps need to know who's logged in throughout the entire app. Context is perfect for this:

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

const AuthContext = createContext();

function AuthProvider({ children }) {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [username, setUsername] = useState("");

  const login = (name) => {
    setUsername(name);
    setIsLoggedIn(true);
  };

  const logout = () => {
    setUsername("");
    setIsLoggedIn(false);
  };

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

function LoginButton() {
  const { isLoggedIn, login } = useContext(AuthContext);

  if (isLoggedIn) {
    return null;
  }

  return <button onClick={() => login("Alice")}>Login</button>;
}

function UserGreeting() {
  const { isLoggedIn, username } = useContext(AuthContext);

  return isLoggedIn ? <h1>Welcome, {username}!</h1> : <h1>Guest</h1>;
}

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

πŸ“Š Prop Drilling vs Context

AspectProp DrillingContext
Data flowThrough every levelDirect access
Intermediate componentsNeed to pass propsUnaware of data
Code clarityCumbersome with deep nestingClean and simple
PerformanceUsually fineCan be optimized
Best forDirect parent-childApp-wide data

πŸ”‘ Key Takeaways

  • βœ… Context solves the prop drilling problem
  • βœ… Use Context for data that many components need
  • βœ… Avoid Context for data that changes frequently (performance impact)
  • βœ… Context is perfect for authentication, themes, and app settings
  • βœ… Context requires a Provider at the top level
  • βœ… Any component inside the Provider can access the Context
  • βœ… Context data is shared across your entire app

Ready to practice? Challenges | Next: Creating Context


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep β€’ Build Real β€’ Verify Skills β€’ Launch Forward

Courses

PythonFastapiReactJSCloud

Β© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn