Context API
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:
Card: A simple UI card component.
ThemeBtn: A toggle button to switch between light and dark themes.
ThemeContext: Context API implementation for managing theme state.
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.
Subscribe to my newsletter
Read articles from Aaks directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by