React Hook recipe from https://usehooks.com. Demo: https://codesandbox.io/s/p33j1m0mxj
// Usage | |
function App() { | |
const [darkMode, setDarkMode] = useDarkMode(); | |
return ( | |
<div> | |
<div className="navbar"> | |
<Toggle darkMode={darkMode} setDarkMode={setDarkMode} /> | |
</div> | |
<Content /> | |
</div> | |
); | |
} | |
// Hook | |
function useDarkMode() { | |
// Use our useLocalStorage hook to persist state through a page refresh. | |
// Read the recipe for this hook to learn more: usehooks.com/useLocalStorage | |
const [enabledState, setEnabledState] = useLocalStorage('dark-mode-enabled'); | |
// See if user has set a browser or OS preference for dark mode. | |
// The usePrefersDarkMode hook composes a useMedia hook (see code below). | |
const prefersDarkMode = usePrefersDarkMode(); | |
// If enabledState is defined use it, otherwise fallback to prefersDarkMode. | |
// This allows user to override OS level setting on our website. | |
const enabled = | |
typeof enabledState !== 'undefined' ? enabledState : prefersDarkMode; | |
// Fire off effect that add/removes dark mode class | |
useEffect( | |
() => { | |
const className = 'dark-mode'; | |
const element = window.document.body; | |
if (enabled) { | |
element.classList.add(className); | |
} else { | |
element.classList.remove(className); | |
} | |
}, | |
[enabled] // Only re-call effect when value changes | |
); | |
// Return enabled state and setter | |
return [enabled, setEnabledState]; | |
} | |
// Compose our useMedia hook to detect dark mode preference. | |
// The API for useMedia looks a bit weird, but that's because ... | |
// ... it was designed to support multiple media queries and return values. | |
// Thanks to hook composition we can hide away that extra complexity! | |
// Read the recipe for useMedia to learn more: usehooks.com/useMedia | |
function usePrefersDarkMode() { | |
return useMedia(['(prefers-color-scheme: dark)'], [true], false); | |
} |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
@dimitarnestorov Thanks, changed it to |
This comment has been minimized.
This comment has been minimized.
This is small but will help users get in the right mindset of effect hooks. I think the comment |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
You should wrap the
useEffect
callback inrequestAnimationFrame