Skip to content

Instantly share code, notes, and snippets.

@alissaVrk
Last active April 14, 2023 14:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alissaVrk/cfbf197066357d89a0132ca550b3efa4 to your computer and use it in GitHub Desktop.
Save alissaVrk/cfbf197066357d89a0132ca550b3efa4 to your computer and use it in GitHub Desktop.
import { set, unset, get, PropertyPath } from 'lodash';
import { useSyncExternalStore } from 'react';
export type SimpleReactiveStore = ReturnType<typeof createSimpleReactiveStore>;
/**
*
* @returns a simple store you can use with your react components.
*/
export function createSimpleReactiveStore() {
const data: object = {};
const registry: ((data: object) => void)[] = [];
function subscribe(listener: (data: object) => void) {
registry.push(listener);
return () => {
registry.splice(registry.indexOf(listener), 1);
};
}
/**
*
* @param path
* @param value has to be an immutable value if you want it to trigger a re-render.
*/
function setValue<T>(path: PropertyPath, value: T) {
if (value === undefined) {
unset(data, path);
} else {
set(data, path, value);
}
registry.forEach((li) => li(data));
}
function getValue<T>(path: PropertyPath) {
return get(data, path) as T;
}
function useValue<T>(path: PropertyPath, defaultValue: T) {
const value = useSyncExternalStore(subscribe, () => getValue<T>(path) || defaultValue);
return value;
}
return {
useValue,
setValue,
getValue,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment