All topics
Hooksadvanced

useSyncExternalStore

Learn how useSyncExternalStore safely subscribes React components to external, mutable data sources under concurrent rendering.

useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?) is the official hook for reading data from a store that lives outside React — like a third-party state library, a browser API such as window.innerWidth, or a custom event-emitter-based store — while remaining correct under React 18's concurrent rendering features.

It's like a newsroom pulling live wire feed updates: useSyncExternalStore is the strict editorial rule that every article printed in a single edition (one render) uses the exact same version of a breaking story, even if the wire service pushes an update while the presses (React's concurrent renderer) are mid-run.

Key Concepts

1
Before this hook existed, subscribing to external stores with useEffect and local useState could produce subtle bugs called tearing, where different parts of the UI observe different values from the same external store during a single render because concurrent rendering can interleave work in ways that a naive subscription doesn't account for.
tearinguseEffectuseState
2
subscribe registers a callback the store calls whenever it changes (returning an unsubscribe function), and getSnapshot returns the current value, which React calls during render and compares to detect changes; the optional third argument, getServerSnapshot, supplies a snapshot during server-side rendering. Most application developers won't call this hook directly very often — it's primarily the mechanism state management libraries (Redux, Zustand, Jotai) use internally to be concurrent-rendering-safe.
subscribegetSnapshotgetServerSnapshot
3
Interviewers rarely expect deep familiarity unless testing senior/library-author-level knowledge, but a solid answer connects useSyncExternalStore to the tearing problem it solves and recognizes that libraries like Redux's useSelector and Zustand build on it under the hood.
useSyncExternalStoreuseSelector