Context API

AaksAaks
3 min read

In this blog, I'll share what I learned about using the Context API in React to implement a theme toggle feature. While I have explored the Context API before, this time I approached it a bit differently. I'll walk you through how I created a simple and effective theme switcher that allows users to toggle between light and dark modes with a single click. This method showcases a clean and organized approach to state management, making it easy to maintain and extend.

Overview

The project consists of the following components:

  1. Card: A simple UI card component.

  2. ThemeBtn: A toggle button to switch between light and dark themes.

  3. ThemeContext: Context API implementation for managing theme state.

  4. App: The main component integrating everything.

Step 1: Setting Up the Theme Context

In the Theme.js file, I created a ThemeContext and a custom hook useTheme to simplify accessing the theme functions across components. The ThemeProvider supplies the theme state (themeMode) and functions (darkTheme and lightTheme) to all children components.

import { createContext, useContext } from "react";

export const ThemeContext = createContext({
  themeMode: "light",
  darkTheme: () => {},
  lightTheme: () => {},
});

export const ThemeProvider = ThemeContext.Provider;

export default function useTheme() {
  return useContext(ThemeContext);
}

Step 2: Creating the Theme Toggle Button Component

The ThemeBtn component allows users to switch themes. It uses the useTheme hook to access the current theme and functions for toggling between light and dark modes.

import React from 'react';
import useTheme from '../context/Theme';

export default function ThemeBtn() {
  const { themeMode, lightTheme, darkTheme } = useTheme();

  const onChangeBtn = (e) => {
    const darkModeStatus = e.currentTarget.checked;
    darkModeStatus ? darkTheme() : lightTheme();
  };

  return (
    <label>
      <input
        type="checkbox"
        className=""
        onChange={onChangeBtn}
        checked={themeMode === 'dark'}
      />
      <span>Toggle Theme</span>
    </label>
  );
}

Step 3: Implementing Theme Switching Logic

In the App.jsx file, we handle the actual logic for switching themes. We maintain themeMode in the state and use useEffect to apply the correct class (light or dark) to the HTML document.

import { useState, useEffect } from 'react';
import { ThemeProvider } from './context/Theme';
import ThemeBtn from './component/ThemeBtn';
import Card from './component/Card';

function App() {
  const [themeMode, setThemeMode] = useState("light");

  const lightTheme = () => {
    setThemeMode("light");
  };

  const darkTheme = () => {
    setThemeMode("dark");
  };

  useEffect(() => {
    document.querySelector('html').classList.remove("light", "dark");
    document.querySelector('html').classList.add(themeMode);
  }, [themeMode]);

  return (
    <ThemeProvider value={{ themeMode, lightTheme, darkTheme }}>
      <div className="flex flex-wrap min-h-screen items-center">
        <div className="w-full max-w-sm mx-auto">
          <div className="w-full max-w-sm mx-auto flex justify-end mb-4">
            <ThemeBtn />
          </div>
          <Card />
        </div>
      </div>
    </ThemeProvider>
  );
}

export default App;

Step 4: Creating the Card Component

The Card component is a simple UI element that does not interact directly with the theme but will automatically reflect the styles applied by the theme toggling.

import React from 'react';

export default function Card() {
  return (
    <div className="dark:bg-gray-800 dark:border-gray-700">
      <a href="/">
        <img className="" src="" alt='i am img' />
      </a>
      <div className="">
        <a href="/">
          <h5 className="text-xl text-gray-900 dark:text-white">
            Lorem ipsum dolor sit amet consectetur adipisicing elit.
          </h5>
        </a>
        <div className="">
          <span className="text-3xl text-gray-900 dark:text-white">$599</span>
          <a
            href="/"
            className="text-white bg-blue-700 hover:bg-blue-800 text-center dark:bg-blue-600 dark:hover:bg-blue-700"
          >
            Add to cart
          </a>
        </div>
      </div>
    </div>
  );
}

Conclusion

Today, I learned how to effectively manage global state using the Context API, specifically for implementing a theme toggle feature. I discovered how to keep the code clean and organized, ensuring that different parts of the application can easily access and modify the theme. By using useContext and creating a custom hook, I saw how straightforward it can be to extend this functionality, making it scalable and easy to maintain in the future.

0
Subscribe to my newsletter

Read articles from Aaks directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Aaks
Aaks