useDarkMode()

This React Hook offers you an interface to enable, disable, toggle and read the dark theme mode. The returned value (isDarkMode) is a boolean to let you be able to use with your logic.

It uses internally useLocalStorage() to persist the value and listens the OS color scheme preferences.

The Hook

1// See: https://usehooks-ts.com/react-hook/use-local-storage
2import { useLocalStorage } from '../useLocalStorage'
3// See: https://usehooks-ts.com/react-hook/use-media-query
4import { useMediaQuery } from '../useMediaQuery'
5
6import { useUpdateEffect } from '..'
7
8const COLOR_SCHEME_QUERY = '(prefers-color-scheme: dark)'
9
10interface UseDarkModeOutput {
11 isDarkMode: boolean
12 toggle: () => void
13 enable: () => void
14 disable: () => void
15}
16
17function useDarkMode(defaultValue?: boolean): UseDarkModeOutput {
18 const isDarkOS = useMediaQuery(COLOR_SCHEME_QUERY)
19 const [isDarkMode, setDarkMode] = useLocalStorage<boolean>(
20 'darkMode',
21 defaultValue ?? false,
22 // ?? isDarkOS,
23 )
24
25 // Update darkMode if os prefers changes
26 useUpdateEffect(() => {
27 setDarkMode(isDarkOS)
28 // eslint-disable-next-line react-hooks/exhaustive-deps
29 }, [isDarkOS])
30
31 return {
32 isDarkMode,
33 toggle: () => setDarkMode(prev => !prev),
34 enable: () => setDarkMode(true),
35 disable: () => setDarkMode(false),
36 }
37}
38
39export default useDarkMode

Usage

1import React from 'react'
2
3import { useDarkMode } from 'usehooks-ts'
4
5export default function Component() {
6 const { isDarkMode, toggle, enable, disable } = useDarkMode()
7
8 return (
9 <div>
10 <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>
11 <button onClick={toggle}>Toggle</button>
12 <button onClick={enable}>Enable</button>
13 <button onClick={disable}>Disable</button>
14 </div>
15 )
16}

Edit on CodeSandbox

See a way to make this page better?
Edit there »