Skip to main content
Practice Problems

What is useSyncExternalStore in React?

What is useSyncExternalStore?

useSyncExternalStore is a React 18+ hook for subscribing to external stores β€” data sources that exist outside React (browser APIs, third-party state libraries, global variables). It ensures consistent reads during concurrent rendering.


Why It's Needed

With concurrent rendering, React may "pause" and "resume" rendering. Without useSyncExternalStore, you might read different values of an external store during a single render β€” a bug called tearing.

Basic API

tsx
const value = useSyncExternalStore( subscribe, // Function to subscribe to changes getSnapshot, // Function to get current value getServerSnapshot // Optional: value for SSR );

Example: Online Status

tsx
function useOnlineStatus() { return useSyncExternalStore( // subscribe β€” called when store changes (callback) => { window.addEventListener("online", callback); window.addEventListener("offline", callback); return () => { window.removeEventListener("online", callback); window.removeEventListener("offline", callback); }; }, // getSnapshot β€” returns current value () => navigator.onLine, // getServerSnapshot β€” value for SSR () => true ); } function StatusBar() { const isOnline = useOnlineStatus(); return <div>{isOnline ? "🟒 Online" : "πŸ”΄ Offline"}</div>; }

Example: Window Width

tsx
function useWindowWidth() { return useSyncExternalStore( (callback) => { window.addEventListener("resize", callback); return () => window.removeEventListener("resize", callback); }, () => window.innerWidth, () => 1024 // Server default ); } function Layout() { const width = useWindowWidth(); return width > 768 ? <DesktopLayout /> : <MobileLayout />; }

Example: localStorage

tsx
function useLocalStorage<T>(key: string, initialValue: T) { const subscribe = (callback: () => void) => { window.addEventListener("storage", callback); return () => window.removeEventListener("storage", callback); }; const getSnapshot = () => { const item = localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; }; const getServerSnapshot = () => initialValue; return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); } // Usage function Settings() { const theme = useLocalStorage("theme", "light"); return <div>Current theme: {theme}</div>; }

How State Libraries Use It

Libraries like Zustand and Redux internally use useSyncExternalStore:

tsx
// Simplified Zustand implementation concept function useStore<T>(store: Store<T>, selector: (state: T) => any) { return useSyncExternalStore( store.subscribe, () => selector(store.getState()), () => selector(store.getInitialState()) ); }

When to Use

ScenarioUse
React state (useState, useReducer)❌ Not needed
Browser APIs (online, resize, media query)βœ… useSyncExternalStore
Third-party stores (without React bindings)βœ… useSyncExternalStore
Building a state management libraryβœ… useSyncExternalStore
Reading from localStorage/sessionStorageβœ… useSyncExternalStore

Important:

useSyncExternalStore prevents tearing in concurrent React by ensuring consistent reads from external data sources. Use it for browser APIs, third-party stores, and any non-React state. If you're using React state (useState/useReducer), you don't need it β€” React handles those correctly already.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems