This is an example app I made using create-react-app
to show implementing darkmode using react context with hooks & localStorage.
Features #
Context #
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
📝 Context in React Documentation
Use createContext
to initialize react context.
export const ThemeContext = createContext();
Every Context object comes with a Provider React component that allows consuming components to subscribe to context changes.
Wrap the content in App.js
inside of the Context.Provider
element.
Toggle State #
Use useState
to toggle the state of darkMode
.
const [darkMode, setdarkMode] = useState();
const toggleDark = () => {
setdarkMode(!darkMode)
}
Initialize On Component Load #
Use useEffect
to load the main functions for toggling state once the component is loaded.
useEffect(() => {
setdarkMode(false)
const lsDark = JSON.parse(localStorage.getItem('darkMode'))
if (lsDark) {
setdarkMode(lsDark)
}
}, [])
Store Setting #
One of the easiest ways to store a setting is to utilize localStorage
using localStorage.setItem
& localStorage.getItem
.
Supporting Browser Option #
Most browsers support prefers-color-scheme
option which allows sites to automatically switch to darkmode without user interaction.
This is a boolean value so we just need to check if it equals true.
const prefersDarkMode = () =>
window.matchMedia('(prefers-color-scheme: dark)').matches === true
Component #
Creating a component to toggle darkMode
is pretty simple as state is just a bool
.
The only thing we need to code in is a check to toggle the moon & sun icons.
const ToggleTheme = () => {
const { darkMode, toggleDark } = useContext(ThemeContext);
return (
<div className="darkmode-container">
<button className="toggle-darkmode" onClick={toggleDark}>
{darkMode ? (
<img src={sun} className="sun-icon" alt="sun-icon" />
) : (
<img src={moon} className="moon-icon" alt="moon-icon" />
)}
</button>
</div>
)
}
This project can be downloaded from github.
Webmentions
No Comments Yet