When to Avoid useSyncExternalStore in React

While useSyncExternalStore is a powerful React hook designed to subscribe to external data sources, it is not a one-size-fits-all solution for state management. This article explains when you should avoid using useSyncExternalStore, detailing scenarios where native React state hooks, context, or standard data-fetching libraries are more appropriate for your application’s performance and maintainability.

1. For Internal React State

You should avoid useSyncExternalStore if the state you are managing is local to a component or can be managed within the React lifecycle. If you are not integrating with a third-party, non-React state manager (such as Zustand, Redux, or native browser APIs like window.matchMedia), you should stick to standard hooks like useState or useReducer. Using useSyncExternalStore for internal state adds unnecessary complexity without any performance benefits.

2. When You Need Concurrent Rendering and Transitions

One of the key features of React 18 is concurrent rendering, which allows React to interrupt a slow render to keep the UI responsive (using useTransition or useDeferredValue). useSyncExternalStore is specifically designed to guarantee that the UI stays strictly in sync with the external store, which means it deliberately disables time-slicing and forces synchronous updates to prevent visual “tearing.” If your application relies on transitions to keep the UI responsive during heavy state updates, this hook will bypass those benefits.

3. For Asynchronous Data Fetching

The useSyncExternalStore hook expects synchronous access to the current snapshot of the data. If your data source is asynchronous—such as standard HTTP API fetches, GraphQL queries, or raw Promises—this hook is not suitable on its own. Instead, use established asynchronous state management solutions like TanStack Query (React Query), SWR, or React’s built-in Suspense-based data-fetching patterns.

4. For Simple Derived State

If you need to calculate a value based on existing props or state, you should not spin up an external store. You should compute derived state directly during render, or wrap the calculation in useMemo if it is computationally expensive. Relying on an external store subscription for derived state introduces unnecessary overhead and complicates the data flow of your application.