Skip to main content
useSyncExternalStore is a React Hook that lets you subscribe to an external store.

Parameters

(callback: () => void) => () => void
required
A function that takes a single callback argument and subscribes it to the store. When the store changes, it should call the provided callback. This will cause the component to re-render. The subscribe function should return a cleanup function that unsubscribes.
() => T
required
A function that returns a snapshot of the data in the store that’s needed by the component. While the store has not changed, repeated calls to getSnapshot must return the same value. If the store changes and the returned value is different (compared with Object.is), React will re-render the component.
() => T
A function that returns the initial snapshot of the data in the store. It will be used only during server rendering and during hydration of server-rendered content on the client. The server snapshot must be the same between the client and the server, and is usually serialized and passed from the server to the client.If omitted, rendering the component on the server will throw an error.

Returns

The current snapshot of the store which you can use in your rendering logic.

Usage

Subscribing to an external store

Most React components will only read data from their props, state, and context. However, sometimes a component needs to read data from some store outside of React that changes over time:
  • Third-party state management libraries that hold state outside of React
  • Browser APIs that expose a mutable value and events to subscribe to its changes

Subscribing to a browser API

Another reason to use useSyncExternalStore is when you want to subscribe to a browser API:

Extracting the logic to a custom Hook

Typically you won’t call useSyncExternalStore directly. Instead, you’ll call it from your own custom Hook:

Adding support for server rendering

If your React app uses server rendering, your components will also run outside the browser environment to generate the initial HTML. This creates some challenges:
  • If you’re subscribing to a browser-only API, it won’t work because it doesn’t exist on the server
  • If you’re subscribing to a third-party data store, you’ll need its data to match between the server and client
Provide a getServerSnapshot function:

Common Use Cases

Window dimensions

Media queries

Local storage

Third-party store

Network status

TypeScript

Generic store hook

Troubleshooting

I’m getting an error: “The result of getSnapshot should be cached”

This error means that your getSnapshot function returns a new object on every call:
Alternatively, return a primitive value that can be safely compared:

My subscribe function is called on every render

Make sure your subscribe function is defined outside the component or wrapped in useCallback:

Hydration mismatch on server rendering

If you get a hydration mismatch error, make sure you provided getServerSnapshot:

Best Practices

Keep getSnapshot pure and fast

Memoize expensive snapshots

Extract to custom hooks

Handle server rendering properly

When to use useSyncExternalStore

Use useSyncExternalStore when:
  • ✅ You’re subscribing to a third-party store
  • ✅ You’re subscribing to browser APIs
  • ✅ You’re building a state management library
  • ✅ You need to integrate with external mutable state
Don’t use it for:
  • ❌ React state (useState, useReducer)
  • ❌ React context (useContext)
  • ❌ Props passed from parent
  • ❌ Local component state