Bridging External Stores with useSyncExternalStore in React Native
Learn how React Native's useSyncExternalStore hook can safely connect any external state source—like Zustand or a custom store—to React's concurrent rendering pipeline.
Insight
React 18 introduced useSyncExternalStore to give libraries a stable way to expose external state to React while preserving consistency under concurrent rendering. In React Native this means you can hook up a lightweight custom store (or an existing one like Zustand) without relying on Context or Redux‑Toolkit providers, keeping your component tree shallow and improving render performance.
Example
// simpleExternalStore.ts
type Listener = () => void;
let state = { count: 0 };
const listeners = new Set<Listener>();
export const getState = () => state;
export const setState = (next: Partial<typeof state>) => {
state = { ...state, ...next };
listeners.forEach(l => l());
};
export const subscribe = (listener: Listener) => {
listeners.add(listener);
return () => listeners.delete(listener);
};
// Counter.tsx
import { useSyncExternalStore } from 'react';
import { getState, subscribe, setState } from './simpleExternalStore';
export default function Counter() {
const count = useSyncExternalStore(subscribe, () => getState().count);
return (
<Button title={`Count: ${count}`} onPress={() => setState({ count: count + 1 })} />
);
}
Takeaway
Wrap any external store with subscribe, getSnapshot, and getServerSnapshot (if needed) and feed it to useSyncExternalStore. This gives you a lock‑step, concurrent‑safe subscription without extra providers, making state sharing across screens lightweight and future‑proof.