UNPKG

@lesnoypudge/utils-react

Version:

lesnoypudge's utils-react

57 lines (56 loc) 1.76 kB
import { useConst } from "../useConst/useConst.js"; import { invariant, noop } from "@lesnoypudge/utils"; import { useRef } from "react"; const useRefManager = (initialValue) => { const isInEffectRef = useRef(false); const effectCallbackToCleanup = useConst(() => { return /* @__PURE__ */ new Map(); }); const manager = useConst(() => { const throwIfRefChanged = (callback) => { isInEffectRef.current = true; callback(); isInEffectRef.current = false; }; const rawManager = { current: initialValue, effect: (callback) => { throwIfRefChanged(() => { effectCallbackToCleanup.set(callback, callback(rawManager.current) ?? noop); }); return () => { throwIfRefChanged(() => { var _a; (_a = effectCallbackToCleanup.get(callback)) == null ? void 0 : _a(); effectCallbackToCleanup.delete(callback); }); }; } }; const notifyEffects = (value) => { throwIfRefChanged(() => { for (const [callback, cleanup] of effectCallbackToCleanup) { cleanup(); effectCallbackToCleanup.set(callback, callback(value) ?? noop); } }); }; const proxy = new Proxy(rawManager, { set: (target, propertyKey, value, receiver) => { if (propertyKey === "current") { invariant(!isInEffectRef.current, "Cannot change value of ref manager during effect"); target.current = value; notifyEffects(value); return true; } return Reflect.set(target, propertyKey, value, receiver); } }); return proxy; }); return manager; }; export { useRefManager }; //# sourceMappingURL=useRefManager.js.map