← All material

React · 2 of 2

useSyncExternalStore

With the store in place, a component reads it in a single call — no useState holding a copy, no useEffect keeping that copy in sync:

import { useSyncExternalStore } from "react";
import { subscribe, getSnapshot } from "./cart-store.js";

const CartBadge = () => {
  const cart = useSyncExternalStore(subscribe, getSnapshot);

  return <span>{cart.items.length}</span>;
};

React Component subscribes in the render function and re-reads the snapshot whene the listener is fired by the store. It also re-reads before committing and restarts the render if the value moved, so every component reading the store in one commit sees the same value.

Implementation advice - Wrap it in a hook

Suggest you define outside the component rather than inline and give more descriptive names:

// cart-hooks.js
import { useSyncExternalStore } from "react";
import { subscribe, getSnapshot } from "./cart-store.js";

const getCount = () => getSnapshot().items.length;

export const useCartCount = () => {
  return useSyncExternalStore(subscribe, getCount);
};

Components import useCartCount and never touch the store directly, so React's dependency on it is one hook in one file.

If the store snapshot contains more data than you need, you can use the hook to only return what you need.