useSyncExternalStore Hook

🪝 Introduction to useSyncExternalStore

The useSyncExternalStore Hook is a React Hook that lets components subscribe to an external data store. It keeps React components synchronized with data that exists outside React, such as browser APIs, global state libraries, or custom stores, while ensuring consistent rendering.

Important

useSyncExternalStore is intended for subscribing to external stores. Most applications using only React state do not need this Hook.

🎯 Why Use useSyncExternalStore?

React state managed with Hooks such as useState lives inside React. However, some applications rely on data managed outside React, including browser APIs, custom event emitters, or state management libraries. useSyncExternalStore provides a standard way to subscribe to these external sources and ensures React always renders using a consistent snapshot of the store.

  • Subscribe to external stores.
  • Keep React synchronized with outside data.
  • Support concurrent rendering safely.
  • Reduce manual subscription logic.

⚙️ Syntax

Basic Syntax

const snapshot = useSyncExternalStore(
  subscribe,
  getSnapshot,
  getServerSnapshot
);
ParameterDescription
subscribeRegisters a listener and returns an unsubscribe function.
getSnapshotReturns the current value from the external store.
getServerSnapshotProvides the snapshot during server-side rendering. This parameter is optional for client-only applications.

🔄 How useSyncExternalStore Works

Component Renders
React Reads the Current Snapshot
Component Subscribes to the External Store
Store Changes
React Reads a New Snapshot
Component Re-renders with Updated Data

💻 Example 1: Custom External Store

Basic Store Subscription

import { useSyncExternalStore } from "react";

const store = {
  value: 0,
  listeners: new Set(),

  subscribe(listener) {
    this.listeners.add(listener);

    return () => {
      this.listeners.delete(listener);
    };
  },

  getSnapshot() {
    return this.value;
  }
};

function Counter() {
  const count = useSyncExternalStore(
    store.subscribe.bind(store),
    store.getSnapshot.bind(store)
  );

  return <h2>{count}</h2>;
}

The component automatically re-renders whenever the external store notifies its subscribers.

💻 Example 2: Browser Online Status

Tracking Network Status

import { useSyncExternalStore } from "react";

function subscribe(callback) {
  window.addEventListener("online", callback);
  window.addEventListener("offline", callback);

  return () => {
    window.removeEventListener("online", callback);
    window.removeEventListener("offline", callback);
  };
}

function getSnapshot() {
  return navigator.onLine;
}

function NetworkStatus() {
  const isOnline = useSyncExternalStore(
    subscribe,
    getSnapshot
  );

  return (
    <p>
      {isOnline ? "Online" : "Offline"}
    </p>
  );
}

Whenever the browser's network status changes, the component automatically updates to display the latest state.

📊 Manual Subscription vs useSyncExternalStore

Manual SubscriptionuseSyncExternalStore
Requires useEffect and cleanup.Handles subscriptions using a standard API.
More boilerplate code.Cleaner subscription logic.
Easy to introduce synchronization bugs.Designed for consistent rendering.
Manual snapshot management.React reads snapshots automatically.

📅 Subscription Lifecycle

🎯 Common Use Cases

Connect React components to external state management libraries.

Monitor browser APIs such as network connectivity or media queries.

Subscribe to custom event emitters or application-wide stores.

Display live data that changes independently of React state.

⚠️ Common Mistakes

  • Using useSyncExternalStore for ordinary React state.
  • Returning inconsistent values from getSnapshot.
  • Forgetting to return an unsubscribe function from subscribe.
  • Using this Hook when useState or useContext would be simpler.

Warning

getSnapshot should return the current value of the external store. React compares snapshots to determine when a component needs to update.

📊 useSyncExternalStore vs useEffect

FeatureuseSyncExternalStoreuseEffect
PurposeSubscribe to external stores.Run side effects.
Data SourceExternal state.Any side-effect logic.
Automatic Snapshot ReadingYes.No.
Typical UsageGlobal stores, browser APIs, subscriptions.Fetching data, timers, subscriptions, DOM interactions.

✅ Best Practices

  • Use useSyncExternalStore only for data managed outside React.
  • Ensure subscribe returns a proper cleanup function.
  • Keep getSnapshot fast and predictable.
  • Provide getServerSnapshot when supporting server-side rendering.
  • Continue using React state Hooks for component-local state.

📚 Official Resource

Learn more about useSyncExternalStore in the official React documentation at React useSyncExternalStore Documentation.

Summary

The useSyncExternalStore Hook provides a standardized way to subscribe to external data stores while keeping React components synchronized with the latest data. It is especially valuable for browser APIs, custom stores, and state management libraries, helping developers build reliable, consistent, and concurrent-ready React applications.