Skip to content

Instantly share code, notes, and snippets.

@DarkRoku12
Created December 25, 2023 02:07
Show Gist options
  • Save DarkRoku12/7969c06528f58e5bff12483c83fdf254 to your computer and use it in GitHub Desktop.
Save DarkRoku12/7969c06528f58e5bff12483c83fdf254 to your computer and use it in GitHub Desktop.
React hook: useUnwatched
/* eslint-disable @typescript-eslint/ban-types */
import { AnyRecord, RecordObj, SymbolAddWatcher, SymbolForAll, Watched } from "@hooks/constants";
export default function useUnwatched<T extends AnyRecord>(state: RecordObj<T> = {} as AnyRecord) {
const watchList = {} as Record<string | symbol, Function[]>;
const proxyHandler = {
set(_target: any, prop: any, value: any) {
Reflect.set(state, prop, value);
const propStateSetters = watchList[prop] || [];
const allStateSetters = watchList[SymbolForAll] || [];
const updated = { [prop]: value };
for (const setter of propStateSetters) setter(updated);
for (const setter of allStateSetters) setter(updated);
// Reset it, since React will re-render (and re-add) the watcher again anyway.
watchList[SymbolForAll] = [];
watchList[prop] = [];
return true;
},
get(_target: any, prop: any, receiver?: any) {
if (prop == SymbolAddWatcher) {
return (key: string | symbol, setter: Function) => {
const stateSetters = watchList[key] || [];
stateSetters.push(setter);
watchList[key] = stateSetters;
};
}
return Reflect.get(state, prop, receiver);
},
};
return new Proxy(state, proxyHandler) as Watched<T>;
}
@DarkRoku12
Copy link
Author

DarkRoku12 commented Dec 25, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment