External Store Synchronization with useSyncExternalStore
External Store Synchronization with useSyncExternalStore
Prior to React 18, state management libraries (Redux, Zustand, MobX) relied on useEffect and useState to subscribe to external mutable stores. With the arrival of Concurrent React and interruptible rendering, this naive approach suffered from tearing: a visual bug where different components in the same tree render conflicting data from the same store because the store mutated midway through an interrupted render. useSyncExternalStore solves tearing with guaranteed synchronous consistency.
1. What is "Tearing"?
In graphics and UI development, tearing occurs when a frame displays data from two different points in time:
useSyncExternalStore guarantees that any external store subscription is read synchronously without tearing across the entire concurrent render.
2. API Signature
subscribe(callback): Registers a listener that is invoked whenever the store mutates. Must return a cleanup unsubscribe function.getSnapshot(): Returns an immutable snapshot of current store data. If the store hasn't changed, it must return the exact same referential value.getServerSnapshot(): Returns the snapshot during SSR HTML rendering.
3. Subscribing to Browser APIs: window.navigator.onLine
A common use case is subscribing to native browser events without third-party libraries:
4. Subscribing to Media Queries (window.matchMedia)
5. Critical Rule: Stable getSnapshot References
The function returned by getSnapshot must return a cached or primitive value. If getSnapshot returns a new object literal ({ count: store.count }) on every invocation, React detects an infinite change loop and crashes with:
Always return primitive types or referentially stable memoized slices from getSnapshot.
Practice Quiz
Virtualizing Massive Lists with TanStack Virtual
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Synchronous Layout Calculations with useLayoutEffect | Virtualizing Massive Lists with TanStack Virtual |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.