What is the useSyncExternalStore Hook?
Learn what React's useSyncExternalStore hook does — subscribing to external stores safely, preventing tearing in concurrent rendering, and supporting SSR.
Expected Interview Answer
useSyncExternalStore is a React 18 hook that lets you subscribe a component to an external (non-React) data store in a way that is safe for concurrent rendering, avoiding tearing where different parts of the UI show inconsistent values during a single render.
It takes a subscribe function (registers a callback React calls when the store changes), a getSnapshot function (returns the current value), and an optional getServerSnapshot for server-side rendering and hydration. React reads the snapshot synchronously at the correct time and re-subscribes as needed, guaranteeing that concurrent features like startTransition never expose a stale or mismatched value. Library authors (Redux, Zustand, Jotai) use it internally so their stores integrate correctly with concurrent React.
- Prevents tearing under concurrent rendering
- Standard, safe way to read external mutable stores
- Supports SSR and hydration via getServerSnapshot
- Replaces fragile useEffect-based subscriptions
- Powers modern state libraries internally
- Keeps snapshots consistent within a single render pass
AI Mentor Explanation
useSyncExternalStore is like the single official scoreboard operator who freezes one agreed score the instant a decision is made, so the big screen, TV graphic, and press box all quote the same number. Without that discipline each screen might sample the score at a slightly different moment and disagree — the UI tearing this hook exists to prevent.
Step-by-Step Explanation
Step 1
Provide a subscribe function
Pass a function that registers React's callback with the store and returns an unsubscribe function.
Step 2
Provide getSnapshot
Return the store's current value; it must return a cached, referentially stable result when unchanged.
Step 3
Add getServerSnapshot
For SSR, supply an initial snapshot React can use during server render and hydration.
Step 4
React subscribes and reads
React calls subscribe on mount and reads getSnapshot at safe points, re-rendering when notified.
Step 5
Consistency guaranteed
React uses a single snapshot per render pass, so concurrent rendering never tears the UI.
What Interviewer Expects
- Definition tied to concurrent rendering and tearing
- Knowledge of the three arguments: subscribe, getSnapshot, getServerSnapshot
- Why getSnapshot must return a stable reference when unchanged
- That it replaces manual useEffect + useState subscriptions
- Awareness that state libraries adopt it internally
Common Mistakes
- Returning a new object from getSnapshot every call, causing infinite re-renders
- Forgetting getServerSnapshot and breaking SSR hydration
- Thinking it is a general-purpose replacement for useState
- Not returning an unsubscribe function from subscribe
- Assuming useEffect subscriptions are safe under concurrent React
Best Answer (HR Friendly)
“It is a React hook that safely connects a component to data living outside React, like a shared store. It makes sure that even when React renders in the background, every part of the screen sees the same up-to-date value instead of mismatched ones. Libraries like Redux use it under the hood.”
Code Example
import { useSyncExternalStore } from 'react'
function useOnlineStatus() {
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)
}
function subscribe(callback) {
window.addEventListener('online', callback)
window.addEventListener('offline', callback)
return () => {
window.removeEventListener('online', callback)
window.removeEventListener('offline', callback)
}
}
function getSnapshot() {
return navigator.onLine
}
function getServerSnapshot() {
return true // assume online during SSR
}function StatusBar() {
const isOnline = useOnlineStatus()
return <span>{isOnline ? 'Online' : 'Offline'}</span>
}Follow-up Questions
- What is tearing in concurrent rendering?
- Why must getSnapshot return a stable reference?
- How does getServerSnapshot help during hydration?
- How do Redux and Zustand use this hook internally?
- What was the pre-React-18 pattern this replaces?
MCQ Practice
1. What problem does useSyncExternalStore primarily solve?
It ensures a component reads a consistent external store value per render, preventing UI tearing under concurrent rendering.
2. What must getSnapshot do to avoid infinite re-renders?
If getSnapshot returns a new reference every call, React thinks the store changed each time and re-renders endlessly.
3. What is the third argument to useSyncExternalStore used for?
getServerSnapshot supplies the value used during server rendering and hydration to avoid mismatches.
Flash Cards
What does useSyncExternalStore prevent? — Tearing — inconsistent values shown across the UI during a single concurrent render.
What are its three arguments? — subscribe, getSnapshot, and optional getServerSnapshot.
Why must getSnapshot be referentially stable? — A new reference each call makes React think the store changed, causing infinite re-renders.
Who uses this hook? — State libraries like Redux, Zustand, and Jotai use it internally for concurrent-safe subscriptions.