Skip to content

Instantly share code, notes, and snippets.

@sorrycc
Created July 27, 2022 10:01
Show Gist options
  • Save sorrycc/9c66208de6c2e4c0b981ad5f02aa91e5 to your computer and use it in GitHub Desktop.
Save sorrycc/9c66208de6c2e4c0b981ad5f02aa91e5 to your computer and use it in GitHub Desktop.
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';
function createStore(createState: Function) {
let state: any;
const listeners = new Set<Function>();
const setState = (partial: any, replace: any) => {
const nextState = typeof partial === 'function' ? partial(state) : partial;
if (nextState !== state) {
const previousState = state;
state = replace ? nextState : Object.assign({}, state, nextState);
listeners.forEach((listener) => listener(state, previousState));
}
};
const getState = () => state;
const subscribe = (listener: any) => {
listeners.add(listener);
return () => listeners.delete(listener);
};
const destroy = () => listeners.clear();
const api = { setState, getState, subscribe, destroy };
state = createState(setState, getState, api);
return api;
}
function useStore(api: any, selector: any, equalityFn: any) {
return useSyncExternalStoreWithSelector(
api.subscribe,
api.getState,
api.getState,
selector || api.getState,
equalityFn,
);
}
export function create(createState: Function) {
const api = createStore(createState);
const useBoundStore = (selector?: any, equalityFn?: any) => {
return useStore(api, selector, equalityFn);
};
Object.assign(useBoundStore, api);
return useBoundStore;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment