Пример простого стейт менеджера для React, работающего через хук useSyncExternalStore.
Хук useSyncExternalStore появился в React 18 и позволяет подписаться на изменение внешнего хранилища. Внешним хранилищем может быть что угодно, например, браузер.
useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
Значения в внешнем хранилище могут меняться, а с помощью хука эти изменения можно отследить. Пример стейт менеджера:
import { useSyncExternalStore } from 'react';
export type Listener = () => void;
function createStore<T>({ initialState }: { initialState: T }) {
let subscribers: Listener[] = [];
let state = initialState;
const notifyStateChanged = () => {
subscribers.forEach((fn) => fn());
};
return {
subscribe(fn: Listener) {
subscribers.push(fn);
return () => {
subscribers = subscribers.filter((listener) => listener !== fn);
};
},
getSnapshot() {
return state;
},
setState(newState: T) {
state = newState;
notifyStateChanged();
},
};
}
export function createUseStore<T>(initialState: T) {
const store = createStore({ initialState });
return () => [useSyncExternalStore(store.subscribe, store.getSnapshot), store.setState] as const;
}
export const useCountStore = createUseStore(0);
function Counter() {
const [count, setCount] = useCountStore();
const increment = () => {
setCount(count + 1);
};
/* --snip-- */
}
Если хук useCountStore будет использоваться в нескольких компонентах, то его значение будет общим между всеми компонентами.
https://paripsky.github.io/blog/build-your-own-react-state-management/