DEV Community

Cover image for Build Your Own useSyncExternalStore for React State Subscriptions
HexShift
HexShift

Posted on • Edited on

Build Your Own useSyncExternalStore for React State Subscriptions

React’s useSyncExternalStore hook is designed to connect React components to external sources of truth—like localStorage, WebSocket streams, or even Redux-style stores. While powerful, its internal magic can be hard to grasp. Let’s demystify it by building a simplified version from scratch.

Step 1: Set Up a Basic Store


This store will manage state outside of React and notify listeners when updates occur.

function createStore(initialValue) {
let value = initialValue;
const listeners = new Set();

return {
getSnapshot: () => value,
setValue: (newVal) => {
value = newVal;
listeners.forEach((l) => l());
},
subscribe: (listener) => {
listeners.add(listener);
return () => listeners.delete(listener);
},
};
}

Step 2: Build a Custom Hook


This custom hook mimics the signature of useSyncExternalStore.

import { useEffect, useSyncExternalStore } from "react";

function useCustomStore(store) {
return useSyncExternalStore(
store.subscribe,
store.getSnapshot
);
}

Step 3: Use the Store in a Component


Let’s create a counter component that subscribes to the store and reacts to changes instantly.

const counterStore = createStore(0);

function Counter() {
const count = useCustomStore(counterStore);

return (
<div>
<h2>Count: {count}</h2>
<button onClick={() => counterStore.setValue(count + 1)}>+1</button>
<button onClick={() => counterStore.setValue(count - 1)}>-1</button>
</div>
);
}

✅ Pros


  • Clean separation between state logic and UI.
  • Supports external systems like WebSockets, browser APIs, etc.
  • Fully concurrent-mode safe (when using useSyncExternalStore).

⚠️ Cons


  • Still requires you to manage the store manually (no reducer helpers, etc.).
  • Harder to debug compared to using React state directly.
  • Won’t work in older versions of React (prior to 18).

Wrap-Up


If you’ve ever wanted to connect React to a global event system or shared non-React data, useSyncExternalStore is the right tool—and now you know how to build it yourself. Try swapping in your own state containers, browser listeners, or even signals.

For a much more extensive guide on getting the most out of React portals, check out my full 24-page PDF file on Gumroad. It's available for just $10:

Using React Portals Like a Pro.

If this was helpful, you can support me here: Buy Me a Coffee

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, cherished by the supportive DEV Community. Coders of every background are encouraged to bring their perspectives and bolster our collective wisdom.

A sincere “thank you” often brightens someone’s day—share yours in the comments below!

On DEV, the act of sharing knowledge eases our journey and forges stronger community ties. Found value in this? A quick thank-you to the author can make a world of difference.

Okay