DEV Community

Lokesh
Lokesh

Posted on

useContext in React

Imagine we are building a website with a dark mode feature. Multiple components may need to know whether dark mode is enabled or disabled.

One way to share this data is through props. But passing props through many components can become difficult.

React provides a hook called useContext to solve this problem.

1. What is useContext?

useContext is a React Hook that allows us to access shared data from different components without passing props manually through every level.

In simple words, useContext helps components share data easily.

2. Why do we need useContext?

Let's understand with an example.

Imagine we have three components:

  • App
  • Profile
  • User

The App component has a username that the User component needs.

We can pass the username through props:

function App() {
  const username = "Lokesh";

  return <Profile username={username} />;
}

function Profile({ username }) {
  return <User username={username} />;
}

function User({ username }) {
  return <h2>Hello, {username}</h2>;
}
Enter fullscreen mode Exit fullscreen mode

Here, Profile does not need the username for its own work. It only passes it to User.

When we pass props through components like this, it is called prop drilling.

For deeply nested components, prop drilling can make code difficult to manage.

This is where useContext becomes useful.

3. How does useContext work?

To use useContext, we generally follow three steps:

  1. Create a context.
  2. Provide a value using the Context Provider.
  3. Access that value using useContext.

Let's understand each step.

Step 1: Create a Context

First, import createContext from React and create a context.

import { createContext } from "react";

const UserContext = createContext();
Enter fullscreen mode Exit fullscreen mode

Here:

  • createContext() creates a context object.
  • UserContext is the context we will use to share data.

Step 2: Provide a Value

Now, we need to make the data available to the components that need it.

import { createContext } from "react";

const UserContext = createContext();

function App() {
  const username = "Lokesh";

  return (
    <UserContext.Provider value={username}>
      <Profile />
    </UserContext.Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Let's understand this:

  • UserContext.Provider makes the context value available to its child components.
  • value={username} is the data we want to share.
  • Profile is inside the Provider, so it can access the shared value.

Step 3: Access the Value Using useContext

Now, let's access the username inside the Profile component.

import { useContext } from "react";

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

  return <h2>Hello, {username}</h2>;
}
Enter fullscreen mode Exit fullscreen mode

Here, useContext(UserContext) reads the value provided by UserContext.Provider.

We don't need to pass the username through props anymore.

4. Complete Example

Here is the complete code:

import { createContext, useContext } from "react";

// Creating a context
const UserContext = createContext();

function App() {
  const username = "Lokesh";

  return (
    // Providing the username to child components
    <UserContext.Provider value={username}>
      <Profile />
    </UserContext.Provider>
  );
}

function Profile() {
  return (
    <div>
      <h2>Profile Component</h2>
      <User />
    </div>
  );
}

function User() {
  // Accessing the shared username
  const username = useContext(UserContext);

  return <h3>Welcome, {username}</h3>;
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Output:

Profile Component

Welcome, Lokesh
Enter fullscreen mode Exit fullscreen mode

Notice that the User component can access the username even though the Profile component does not pass it as a prop.

That's the main advantage of useContext.

5. Where is useContext Used?

useContext is useful when multiple components need access to the same data.

Some common examples are:

  • Dark Mode: Share the selected theme across components.
  • Authentication: Share the logged-in user's information.
  • Language Settings: Share the selected language.
  • Shopping Cart: Share cart information across different components.

6. Important Points to Remember

  • createContext() is used to create a context.
  • The Provider makes a value available to its child components.
  • useContext() is used to access the context value.
  • Components must be inside the appropriate Provider to receive its value.
  • useContext helps avoid unnecessary prop drilling.

Top comments (0)