Skip to main content

What does `useSyncExternalStore()` do?

What useSyncExternalStore() does

useSyncExternalStore() connects a React component to external state that React does not manage (for example, Redux, Zustand, an EventEmitter, a custom store, window.location, and so on).

It provides:

  • synchronous reading of the current value (a store snapshot),
  • subscription to updates,
  • correct behavior with concurrent rendering (React 18) and SSR.

More simply: useSyncExternalStore() lets React components reliably read data from an external store and update when it changes.


Syntax

javascript
const state = useSyncExternalStore( subscribe, // subscription function getSnapshot, // function that reads the current state getServerSnapshot? // (optional) version for SSR );

Example: connecting to a custom store

Say we have a simple store outside of React:

javascript
// store.js let listeners = []; let count = 0; export function increment() { count++; listeners.forEach((l) => l()); } export function subscribe(listener) { listeners.push(listener); return () => { listeners = listeners.filter((l) => l !== listener); }; } export function getSnapshot() { return count; }

Now let's connect it to React through useSyncExternalStore:

javascript
import { useSyncExternalStore } from "react"; import { subscribe, getSnapshot, increment } from "./store"; function Counter() { const count = useSyncExternalStore(subscribe, getSnapshot); return ( <div> <p>Count: {count}</p> <button onClick={increment}>+1</button> </div> ); }

Now:

  • The component gets the up-to-date value from getSnapshot() immediately;
  • When the store changes, subscribe() fires -> React re-renders the component;
  • Everything works synchronously and predictably, even in concurrent mode.

What each argument does

ArgumentWhat it does
subscribe(listener)Registers a callback that is called when the state changes; returns an unsubscribe function
getSnapshot()Returns the current value of the state from the external source
getServerSnapshot() (optional)A version of getSnapshot for SSR, so the server and client stay in sync

Why this appeared in React 18

Previously, custom hooks like useStore, useSelector, and so on were used for this. But with the arrival of Concurrent Rendering, React started rendering several versions of the UI "at once".

The problem with the old solutions:

  • They could pick up a "stale" value from the store,
  • Or cause "desynchronization" (the UI showed something different from what was actually in the store).

useSyncExternalStore solves this, because it:

  • Guarantees that React always reads the current snapshot of the state,
  • And updates synchronously if the store changes during rendering.

Example: integration with Redux

Redux 8+ now uses useSyncExternalStore internally.

javascript
import { useSelector } from "react-redux"; function MyComponent() { const count = useSelector((state) => state.counter.value); return <div>{count}</div>; }

Inside, useSelector is implemented roughly like this:

javascript
function useSelector(selector) { return useSyncExternalStore( store.subscribe, () => selector(store.getState()) ); }

Example with window.location (an external source)

javascript
function useLocation() { return useSyncExternalStore( (callback) => { window.addEventListener("popstate", callback); return () => window.removeEventListener("popstate", callback); }, () => window.location.pathname ); } function RouterView() { const path = useLocation(); return <div>Current path: {path}</div>; }

React will automatically update the component when window.location changes.


The SSR version (getServerSnapshot)

With server-side rendering (Next.js, Remix, and so on) you can pass a 3rd argument:

javascript
useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);

This matters so that the value on the server and the client match, otherwise React will emit a "mismatched hydration" warning.


When to use it

WhenWhy
You are connecting to an external store (Redux, Zustand, a custom store)React does not manage this state
You need a reactive subscriptionThe component must re-render when the store changes
It matters to avoid desynchronization in Concurrent RenderinguseSyncExternalStore guarantees consistency
You need safe behavior under SSRYou can pass getServerSnapshot

When you don't need it

CaseWhy
You work with state through useState or useReducerReact manages the data itself - useSyncExternalStore is unnecessary
You are making API requestsUse useEffect / React Query
The store is local, not globalOverkill

Summary

QuestionAnswer
What does useSyncExternalStore() doLets a React component subscribe to external state (a store) and get up-to-date data
Arguments(subscribe, getSnapshot, getServerSnapshot?)
Why it is neededFor state consistency under Concurrent Rendering and SSR
Where it is usedRedux, Zustand, Jotai, custom stores, event emitters
Do not use it forLocal React state (useState, useReducer)

Main idea:

useSyncExternalStore() is the "official way" to synchronously connect React to external state without the risk of desynchronization between the store and the UI.

Short Answer

Interview ready
Premium

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