React: Make theme toggler with just 10 lines of code.
Ever wondered how the theme toggler works? Well, here's the explanation and no need to understand and update every DOM for just themes.
Theming is an important feature in many applications, allowing users to customize the color scheme and improve accessibility. In this article, we'll build a theme toggler in React that can switch between a light and dark theme. Here's the live demo and GitHub repo if you ever feel like contributing to advancement or using it in your project as a template.
Context API
We'll use the Context API to manage the theme state and make it available to any component. Context provides a way to pass data through the component tree without having to pass props manually at every level.
First, create a context then create a context provider that wraps our app:
import React, { createContext } from "react";
export const ThemeContext = createContext();
export default function ThemeProvider({ children }) {
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
Any component within this provider can subscribe to the context:
import { ThemeContext } from "./ThemeContext";
export default function App() {
const { theme, toggleTheme } = React.useContext(ThemeContext);
return { /* ... */ };
}
This allows us to pass these data through the context and use it in any component.
State Management
We'll store the current theme in state and provide setters to toggle the theme.
export default function ThemeProvider({ children }) {
const [theme, setTheme] = React.useState("light");
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
Now any component can call toggleTheme()
from context to switch themes.
Style Switching
We'll dynamically apply a .light
or .dark
class to the body
based on the theme state.
import React from "react";
import { ThemeContext } from "./ThemeContext";
export default function App() {
const { theme, toggleTheme } = React.useContext(ThemeContext);
return (
<div className={`app__container ${theme}`}>
{ /* ... */ }
</div>
);
}
Our CSS will have rules for .light
and .dark
selectors:
*{
margin: 0;
padding: 0;
}
.app__container{
padding: 30px 3vw;
width: 100vw;
height: 100vh;
}
.app__container.light{
background-color: #fff;
}
.app__container.dark{
background-color: #000;
color: #fff;
}
Now whenever the theme state changes, the corresponding class will be applied, switching the styles.
Theme Toggle Button
We'll create a button component that toggles the theme:
<button onClick={toggleTheme}>Toggle Theme</button>
When this button is clicked, it will call toggleTheme()
from context, toggling the theme state and re-applying the styles.
Storing in Local Storage
We can persist the theme state by storing it in localStorage
:
function toggleTheme() {
const _theme = theme === "light" ? "dark" : "light";
localStorage.setItem("13x54r_theme", _theme);
setTheme(_theme);
}
Now when the page reloads, it will get the saved theme from localStorage
and apply the correct styles. Here's the complete Code for the theme context.
import React, { createContext } from "react";
export const ThemeContext = createContext();
export default function ThemeProvider({ children }) {
const [theme, setTheme] = React.useState("light");
React.useEffect(() => {
const prevTheme = localStorage.getItem("13x54r_theme");
if (prevTheme) {
setTheme(prevTheme);
}
}, []);
function toggleTheme() {
const _theme = theme === "light" ? "dark" : "light";
localStorage.setItem("13x54r_theme", _theme);
setTheme(_theme);
}
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
Hope this helps explain how to build a theme toggler in React! Happy Hacking!