2024's Update: just use Next themes
In this quick article, I will be implementing dark mode to a quick React app with a custom React hook,
Before we start, let's see how is this supposed to work in three easy steps:
- We will check first if the chosen theme isn't stored on localStorage
- If it exists, we will simply set it as the default theme
- Otherwise, we will have to use the light theme as the default one
So let's get started!
Let's start by setting up the custom hook first, we will be using useEffect
& useState
imported from React, we will check localStorage when the component mounts for the first time, then we'll follow the second step!
import { useEffect, useState } from 'react'
export default () => {
const [theme, setTheme] = useState('light')
useEffect(() => {
const localTheme = window.localStorage.getItem('components/theme')
if (localTheme) {
setTheme(localTheme)
}
}, [])
}
Let's setup a function now that toggles in between themes and stores the selected theme in localStorage
import { useEffect, useState } from 'react'
export default () => {
const [theme, setTheme] = useState('light')
const toggleTheme = () => {
if (theme === 'light') {
window.localStorage.setItem('theme', 'dark')
setTheme('dark')
} else {
window.localStorage.setItem('theme', 'light')
setTheme('light')
}
}
useEffect(() => {
const localTheme = localStorage.getItem('components/theme')
if (localTheme) {
setTheme(localTheme)
}
}, [])
}
All good now, we only need to return the theme value along with the function so we can access it when we import the custom hook!
import { useEffect, useState } from 'react'
export default () => {
const [theme, setTheme] = useState('light')
const toggleTheme = () => {
if (theme === 'light') {
window.localStorage.setItem('theme', 'dark')
setTheme('dark')
} else {
window.localStorage.setItem('theme', 'light')
setTheme('light')
}
}
useEffect(() => {
const localTheme = window.localStorage.getItem('components/theme')
if (localTheme) {
setTheme(localTheme)
}
}, [])
return [theme, toggleTheme]
}
Finally, let's see how we can use it when we import it
import React from 'react'
import useDarkMode from './useDarkMode'
export default () => {
const [theme, toggleTheme] = useDarkMode()
return (
<div
style={{
background: theme === 'dark' ? '#000' : '#fff',
color: theme === 'dark' ? '#fff' : '#000',
}}
>
<button type="button" onClick={toggleTheme}>
Switch theme
</button>
</div>
)
}
You can find the full example here