JAVASCRIPT
Implement Theme Toggling with a `useDarkMode` React Hook
Effortlessly add dark mode functionality to your React application using a custom `useDarkMode` hook, enhancing user experience and accessibility with persistent themes.
import React, { useState, useEffect } from 'react';
function useDarkMode() {
const [isDarkMode, setDarkMode] = useState(() => {
// Check user's preferred color scheme or local storage on initial load
try {
const storedMode = window.localStorage.getItem('dark-mode');
if (storedMode !== null) {
return JSON.parse(storedMode);
}
return window.matchMedia('(prefers-color-scheme: dark)').matches;
} catch (error) {
console.error("Error reading dark mode from local storage", error);
return false;
}
});
useEffect(() => {
// Apply or remove 'dark' class to the body element
const bodyClass = document.body.classList;
isDarkMode ? bodyClass.add('dark') : bodyClass.remove('dark');
// Persist preference to local storage
try {
window.localStorage.setItem('dark-mode', JSON.stringify(isDarkMode));
} catch (error) {
console.error("Error writing dark mode to local storage", error);
}
}, [isDarkMode]);
return [isDarkMode, setDarkMode];
}
function App() {
const [isDarkMode, setDarkMode] = useDarkMode();
const toggleDarkMode = () => {
setDarkMode(prevMode => !prevMode);
};
return (
<div style={{ padding: '20px', minHeight: '100vh',
backgroundColor: isDarkMode ? '#333' : '#f0f0f0',
color: isDarkMode ? '#f0f0f0' : '#333' }}>
<h1>Welcome to my App</h1>
<button onClick={toggleDarkMode}>
Toggle {isDarkMode ? 'Light' : 'Dark'} Mode
</button>
<p>This is some content.</p>
</div>
);
}
// Remember to add a basic CSS rule like:
// body.dark { background-color: #333; color: #f0f0f0; }
// This example applies inline styles for demonstration.
export default App;
How it works: The `useDarkMode` hook manages the dark mode state for your application. It initializes `isDarkMode` by checking local storage and the user's system preference (`prefers-color-scheme`). A `useEffect` hook then adds or removes a 'dark' class to the `document.body` element, allowing CSS to apply themes globally. It also persists the user's preference in local storage, ensuring their choice is remembered across sessions. The hook returns the current `isDarkMode` state and a function to toggle it.