Skip to content

Instantly share code, notes, and snippets.

Last active March 26, 2021 08:24
What would you like to do?
// Usage
function App() {
const [darkMode, setDarkMode] = useDarkMode();
return (
<div className="navbar">
<Toggle darkMode={darkMode} setDarkMode={setDarkMode} />
<Content />
// Hook
function useDarkMode() {
// Use our useLocalStorage hook to persist state through a page refresh.
// Read the recipe for this hook to learn more:
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
() => {
const className = 'dark-mode';
const element = window.document.body;
if (enabled) {
} else {
[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:
function usePrefersDarkMode() {
return useMedia(['(prefers-color-scheme: dark)'], [true], false);
Copy link

You should wrap the useEffect callback in requestAnimationFrame

Copy link

global? Shouldn't that be window?

Copy link

@DimitarNestorov Thanks, changed it to window and moved into useEffect callback to avoid SSR issues with window not being defined. What is the rationale behind wrapping the callback in requestAnimationFrame? Since this effect fires infrequently seems like an unnecessary performance optimization to me.

Copy link

This is small but will help users get in the right mindset of effect hooks. I think the comment // Only re-call effect when value changes should say something to like // Sync this effect with the "enabled" state. This comes with the explanation of the new mental model behind the effect hook by Ryan Florence -

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment