I've been diving into a helpful tutorial on implementing dark mode toggle in my project. The tutorial uses react-toggle and can be found here. Everything seems to be working fine except for one issue that arises on the initial page load.
When the browser has 'prefers-color-scheme: dark', the dark mode toggle doesn't receive the 'react-toggle--checked' class until I make a local change in VSCode and save it. Only then does the class get applied properly.
Before saving: https://i.sstatic.net/aOAho.png
After saving: https://i.sstatic.net/9RX9O.png
I'm puzzled as to why this behavior is occurring. The initial value of 'isDark' is true, hence the Toggle's 'checked' value should also be true and trigger the application of the 'react-toggle--checked' class. Why does making a local change in the editor and saving fix this issue?
The technologies being used are Next.js and React.
useColorScheme.js
import { useEffect, useMemo } from 'react'
import { useMediaQuery } from 'react-responsive'
import createPersistedState from 'use-persisted-state'
const useColorSchemeState = createPersistedState('colorScheme')
export function useColorScheme() {
const systemPrefersDark = useMediaQuery(
{
query: '(prefers-color-scheme: dark)',
},
undefined,
);
const [isDark, setIsDark] = useColorSchemeState()
const value = useMemo(() => isDark === undefined ? !!systemPrefersDark : isDark,
[isDark, systemPrefersDark])
useEffect(() => {
if (value) {
document.body.classList.add('dark')
} else {
document.body.classList.remove('dark')
}
}, [value])
return {
isDark: value,
setIsDark
}
}
ColorSchemeToggle.js
import Toggle from 'react-toggle'
import { useColorScheme } from './useColorScheme'
// Styles
import 'react-toggle/style.css'
const ColorSchemeToggle = () => {
const { isDark, setIsDark } = useColorScheme()
return (
<Toggle
checked={isDark}
onChange={({ target }) => setIsDark(target.checked)}
aria-label='Dark mode toggle'
className={`dark-mode-toggle`}
/>
)
}
export default ColorSchemeToggle