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 useuseSyncExternalStore is when you want to subscribe to a browser API:
Extracting the logic to a custom Hook
Typically you won’t calluseSyncExternalStore 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
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 yourgetSnapshot function returns a new object on every call:
My subscribe function is called on every render
Make sure yoursubscribe 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 providedgetServerSnapshot:
Best Practices
Keep getSnapshot pure and fast
Memoize expensive snapshots
Extract to custom hooks
Handle server rendering properly
When to use useSyncExternalStore
UseuseSyncExternalStore 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
- ❌ React state (
useState,useReducer) - ❌ React context (
useContext) - ❌ Props passed from parent
- ❌ Local component state