bhylu.com

Advertisements

React useSyncExternalStore

Use useSyncExternalStore when data already lives in an external subscription system.

How it works

Some applications must read an existing store rather than move all data into React state. useSyncExternalStore accepts a subscribe function and a snapshot reader. The snapshot must be stable while the data is unchanged. This example’s tiny module-level store holds one desk status and notifies subscribers when it changes. It is a teaching boundary, not a recommendation to replace every local state hook with a custom store.

Run the code

Use a separate empty lab folder with Node 22.12+ in the 22 series. Save the files below using their displayed paths; browsers may download only the basename, so create src, public or tests folders as listed. The pinned project uses React and React DOM 19.3.1 with Vite 7.3.1. Run npm install, then npm run dev and open the local address Vite prints. React examples do not run in Bhylu’s current playground.

No Apache, MySQL or change to Bhylu’s server configuration is needed. These are local teaching projects, not a publishing package. Keep generated dependencies and lockfiles in your own lab. Review the project setup.

Example

src/main.jsx

import React, { StrictMode, useSyncExternalStore } from 'react';
import { createRoot } from 'react-dom/client';
import './style.css';

let status = 'Open';
const subscribers = new Set();
const subscribe = (listener) => {
  subscribers.add(listener);
  return () => subscribers.delete(listener);
};
const getSnapshot = () => status;
function closeDesk() {
  status = 'Closed';
  subscribers.forEach((listener) => listener());
}
function App() {
  const current = useSyncExternalStore(subscribe, getSnapshot, () => 'Open');
  return (
    <main>
      <h1>Neighbourhood lending desk</h1>
      <button onClick={closeDesk}>Close the local desk</button>
      <output>Desk status: {current}</output>
    </main>
  );
}

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

Expected result

Closing the store updates the visible status to Closed.

The snapshot is a primitive string, so unchanged reads are stable. Returning a fresh object on every read would violate the intended snapshot contract unless cached. The third function supplies the server snapshot for server-rendered usage; it must agree with the initial hydrated data. Subscription functions live outside the component here so their identities do not change every render.

For API contracts and version differences, use React’s official documentation.

Advertisements