UNPKG

crootfast

Version:

大前端工程化命令行脚手架

61 lines (57 loc) 1.78 kB
import { useRef } from "react"; // import isPlainObject from 'lodash/isPlainObject'; import { isPlainObject } from "lodash-es"; import { useCreation, useUpdate } from "ahooks"; // k:v 原对象:代理过的对象 const proxyMap = new WeakMap(); // k:v 代理过的对象:原对象 const rawMap = new WeakMap(); function observer(initialVal, cb) { let existingProxy = proxyMap.get(initialVal); // 添加缓存 防止重新构建proxy if (existingProxy) { return existingProxy; } // 防止代理已经代理过的对象 // https://github.com/alibaba/hooks/issues/839 if (rawMap.has(initialVal)) { return initialVal; } let proxy = new Proxy(initialVal, { get: function (target, key, receiver) { let res = Reflect.get(target, key, receiver); // Only proxy plain object or array, // otherwise it will cause: https://github.com/alibaba/hooks/issues/2080 return isPlainObject(res) || Array.isArray(res) ? observer(res, cb) : res; }, set: function (target, key, val) { const oVal = target[key]; if (oVal === val) { // console.log(`尝试设置 ${key},但新旧值相同,无需设置`); return true; } let ret = Reflect.set(target, key, val); cb(); return ret; }, deleteProperty: function (target, key) { let ret = Reflect.deleteProperty(target, key); cb(); return ret; } }); proxyMap.set(initialVal, proxy); rawMap.set(proxy, initialVal); return proxy; } function useReactive(initialState) { let update = useUpdate(); let stateRef = useRef(initialState); let state = useCreation(function () { return observer(stateRef.current, function () { update(); }); }, []); return state; } export default useReactive;