React Context API
@onjsdev

@onjsdev

React Context API


Sep 28 2024

Watch also the video on our youtube channel 👇👇👇

Have you ever faced the challenge of passing data down through multiple levels of components in React? If so, the React Context API can help.

What is the React Context API?

The React context API provides a way to share data across components without the need to pass props through every component in the hierarchy. You can think of it as global state management in your application.

The Context API is particularly useful for data that is:

  • global
  • frequently updated,
  • and used by deeply nested components.

Some common examples include user credentials and login state, user theme preferences, user selected language, or cart state in e-commerce.

Now let's explore how to use the context API in a React application.

How To Use The Context API In A React Application

You can implement the context API in your application in three steps.

  • You create a context
  • provide that context to a part of your app,
  • and consume it wherever it's needed without prop drilling.

In my example, I will create a context to store user's theme preferences. This will allow theme changes made in a component like the navbar to be accessible and reflected in other parts of the application.

In the first step, let's add a folder named Context to the project. This will help us organize our context files and improve code structure. Within this folder, I'll create a file called ThemeContext.js. You can give your context any name that reflects its purpose.

import { createContext, useState } from "react";

export const themeContext = createContext("light");

export function ThemeContextProvider({ children }) {
  const [theme, setTheme] = useState("light");

  function toggleTheme() {
    setTheme(theme === "light" ? "dark" : "light");
  }

  return (
    <themeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </themeContext.Provider>
  );
}

First, in this file, I created a ThemeContext using the CreateContext method. This method takes an argument to set a default value for the context if no provider is available. You can pass the default theme here, which is light in my example.

Next, I created a provider component using this context, which will supply the context data to all child components. Here, children represents the components that will be wrapped inside the provider in the next steps.

The provider component accepts a value prop, defining the data shared with its wrapped components. So, I created a theme state using the useState hook, along with a toggle function to switch the theme preference. Once that's set up, I passed both the theme state and the toggle function to the value prop.

In this step, I need to wrap the components that need access to the context data with the provider component. The app.js file is an ideal location for this, because I can wrap all the components there.

import "./App.css";
import Card from "./components/Card";
import Navbar from "./components/Navbar";
import { ThemeContextProvider } from "./context/ThemeContext";

function App() {
  return (
    <ThemeContextProvider>
      <div className="app">
        <Navbar />
        <Card></Card>
      </div>
    </ThemeContextProvider>
  );
}

export default App;

Now, everything is set, we can move on to the components and use the context data to implement the functionality that allows users to change their theme. Here, the useContext hook is used to retrieve the current theme and toggle function from the value prop in the provider.

import React, { useContext } from "react";
import { themeContext } from "../context/ThemeContext";

const Navbar = () => {
  const { theme, toggleTheme } = useContext(themeContext);

  return (
    <nav className={theme === "light" ? "light-nav" : "dark-nav"}>
      <h1>My App</h1>
      <div>
        <span>Current Theme: {theme}</span>
        <button onClick={toggleTheme}>Toggle Theme</button>
      </div>
    </nav>
  );
};

export default Navbar;

The navbar classes are then dynamically set based on the current theme, and the toggle function is passed to a button on the navbar to allow users to switch themes.

Lastly, let's move on to the Card component and style it based on the current theme, applying the same steps there.

import React, { useContext } from "react";
import { themeContext } from "../context/ThemeContext";

const Card = () => {
  const { theme } = useContext(themeContext);

  return (
    <div className={theme === "light" ? "light-card" : "dark-card"}>
      <h2>Themed Card</h2>
      <p>
        This card's style changes based on the current theme. The current theme
        is: <strong>{theme}</strong>.
      </p>
    </div>
  );
};

export default Card;

Conclusion

In this article we have explored to implement Context API in a react application. Thank you for reading