Skip to content

.tip

ยท one of the small things

useSyncExternalStore for anything outside React

Subscribing to window.matchMedia, a store or localStorage with useEffect and useState tears under concurrent rendering and hydrates wrong. The hook built for it handles both.

const isDark = useSyncExternalStore(
  (cb) => { const m = matchMedia("(prefers-color-scheme: dark)"); m.addEventListener("change", cb); return () => m.removeEventListener("change", cb); },
  () => matchMedia("(prefers-color-scheme: dark)").matches,
  () => false, // server snapshot
);

The third argument is what the server renders, and it's how you avoid the hydration mismatch.

react