Clean β’ Professional
Dark Mode and Theme Switching are essential modern UI features that improve user experience and accessibility.
In React, implementing dynamic themes (like light and dark modes) is simple using CSS variables, React state, or context APIs β and works seamlessly with frameworks like Tailwind CSS or Styled Components.
A theme defines the overall appearance of your app β including colors, backgrounds, typography, and spacing.
Dark mode is one of the most common themes, providing a darker color palette to reduce eye strain and improve usability in low-light environments.
React allows you to dynamically switch between themes by updating component styles, CSS variables, or global classes.
Letβs start with the simplest way β toggling between two themes using Reactβs state and className.
Example: Simple Dark Mode Toggle
import React, { useState } from "react";
import "./App.css"; // contains theme classes
function App() {
const [darkMode, setDarkMode] = useState(false);
return (
<div className={darkMode ? "app dark" : "app"}>
<h1>{darkMode ? "π Dark Mode" : "βοΈ Light Mode"}</h1>
<p>This is a simple example of theme switching in React.</p>
<button onClick={() => setDarkMode(!darkMode)}>
Toggle Theme
</button>
</div>
);
}
export default App;
CSS (App.css)
.app {
background-color: #ffffff;
color: #000000;
transition: all 0.3s ease-in-out;
min-height: 100vh;
text-align: center;
padding: 2rem;
}
.app.dark {
background-color: #121212;
color: #ffffff;
}
If your app has multiple components, managing themes through React Context ensures consistent behavior across the app.
Example: Global Theme Context
ThemeContext.js
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext();
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");
const toggleTheme = () => {
setTheme((prev) => (prev === "light" ? "dark" : "light"));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
return useContext(ThemeContext);
}
App.js
import React from "react";
import { ThemeProvider, useTheme } from "./ThemeContext";
import "./App.css";
function ThemedComponent() {
const { theme, toggleTheme } = useTheme();
return (
<div className={`app ${theme}`}>
<h1>{theme === "dark" ? "π Dark Mode" : "βοΈ Light Mode"}</h1>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}
export default function App() {
return (
<ThemeProvider>
<ThemedComponent />
</ThemeProvider>
);
}
Why use Context?
If youβre using Tailwind CSS, dark mode integration is built-in and very easy to enable.
Step 1: Enable Dark Mode in tailwind.config.js
module.exports = {
darkMode: 'class', // enables dark mode via a class
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
Step 2: Add a Theme Toggle in React
import { useState } from "react";
export default function App() {
const [darkMode, setDarkMode] = useState(false);
return (
<div className={darkMode ? "dark" : ""}>
<div className="min-h-screen flex flex-col items-center justify-center bg-white dark:bg-gray-900 text-black dark:text-white transition-all">
<h1 className="text-3xl font-bold mb-4">
{darkMode ? "π Dark Mode" : "βοΈ Light Mode"}
</h1>
<buttononClick={() => setDarkMode(!darkMode)}
className="px-4 py-2 bg-blue-500 dark:bg-yellow-400 text-white dark:text-black rounded"
>
Toggle Theme
</button>
</div>
</div>
);
}
To remember the userβs theme even after refresh:
import React, { useState, useEffect } from "react";
function App() {
const [theme, setTheme] = useState(localStorage.getItem("theme") || "light");
useEffect(() => {
localStorage.setItem("theme", theme);
document.body.className = theme;
}, [theme]);
return (
<div className="App">
<h1>{theme === "dark" ? "π Dark Mode" : "βοΈ Light Mode"}</h1>
<button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
Toggle Theme
</button>
</div>
);
}
export default App;Β