In React, data usually flows from parent to child using props. But in large apps, passing props through multiple levels of components becomes messy. This problem is called prop drilling.

The React Context API provides a way to share values like themes, user info, or settings between components without passing props manually at every level. It allows you to create a global state that can be accessed by any component in the component tree.

What is Context?

  • Context allows you to create global variables that can be accessed by any component.
  • Useful for things like themes, user authentication, or language settings.

Prop Drilling

Prop drilling happens when you pass data from a parent component to a deeply nested child component, through multiple levels of components — even if some of those middle components don't need the data.

It's like giving a message to a friend by asking three other people to pass it along for you 😅


function App() {
  const user = { name: "Avi", role: "Trainer" };

  return <Dashboard user={user} />;
}
function Dashboard({ user }) {
  return <Profile user={user} />;
}
function Profile({ user }) {
  return <h2>Welcome {user.name}, your role is {user.role}</h2>;
}

In the example above, the user object is passed down through the Dashboard and Profile components as props. This is an example of prop drilling, where data is passed through multiple layers of components.

Prop drilling can make your code harder to maintain, especially as your component tree grows. This is where the Context API comes in handy.


Create Context

To create a context, use the createContext function from React. This function returns a context object, which can be used to provide and consume values. The context object has two components: a Provider and a Consumer.

The Provider component is used to set the context value, while the Consumer component is used to access the context value.

Here's an example:


import { createContext, useContext } from "react";

  // 1. Create Context
const UserContext = createContext();

// 2. Provide Context
function App() {
  const user = { name: "Avi", role: "Trainer" };

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

// 3. Consume Context
function Profile() {
  const user = useContext(UserContext);
  return <h2>Welcome {user.name}, your role is {user.role}</h2>;
}

In this example, we create a context called UserContext using the createContext function. The App component uses the Provider to set the context value, which includes a user object. The Profile component uses the useContext hook to access the context value and display the user's name and role.


Multiple Components

The Context API is especially useful when you have multiple components that need access to the same data. Instead of passing props down through each component, you can use context to share the data directly.

Here's an example:


  function Dashboard() {
  return (
    <div>
      <Profile />
      <Settings />
    </div>
  );
}

function Settings() {
  const user = useContext(UserContext);
  return <p>User Role: {user.role}</p>;
}

Updating Context Value

You can also update the context value by combining it with state.

Updating context value is similar to updating state. You can use the state updater function provided by the context to update the context value.

Here's an example:


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

const ThemeContext = createContext();

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

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

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

  return (
    <div>
      <p>Current Theme: {theme}</p>
      <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
        Toggle Theme
      </button>
    </div>
  );
}

In this example, we create a ThemeContext that holds the current theme and a function to update it. The Toolbar component consumes the context and provides a button to toggle between light and dark themes.



When to Use Context API

The Context API is useful in the following scenarios:

  • When you have global data that needs to be accessed by many components.
  • When you want to avoid prop drilling (passing props through many layers).
  • When you need to share state between components without lifting state up.
  • For themes (light/dark), authentication, language, or app settings.

Avoid overusing Context API for every piece of state. It can make component reuse more difficult.