react hook实现computed

本文最后更新于:2022年6月6日 中午

https://codesandbox.io/s/usecomputedvalue-custom-hook-mo5b4?from-embed

实现类computed的计算属性

type computedValueProps = [() => void, any[]];
function useComputedValue(allArgs: computedValueProps) {
	// normally setting current during render like this is not good and you'll
	// want to do that in a useEffect.
	// However, we need access to these values *during* render.
	const args = React.useRef<computedValueProps>();
	args.current = allArgs;   // ⚠️每次render,拿到最新的参数
	const ref = React.useRef<{
		__value: any;
		__deps: any[];
	}>();
	if (!ref.current) {
		ref.current = {
			__value: null,
			__deps: null,
		};
		Object.defineProperty(ref.current, "result", {
			get() {
				const [cb, deps] = args.current; // ⚠️cb是()=>void,

				// only call the given callback if we haven't already calculated
				// the value or the dependencies have changed.
				if (
					!ref.current.__value ||
					!ref.current.__deps ||
					!ref.current.__deps.every((dep, i) => Object.is(dep, deps[i]))
          // ⚠️Object.is严格比较是否依赖的参数变化了
				) {
					ref.current.__value = cb();
					ref.current.__deps = deps;
				}
				return ref.current.__value;
			},
		});
	}
	return ref.current;
}

Usage

const someValue = useComputedValue(()=>calculateValue(somearg),[somearg])

// render
someValue.result
  • 使用useRef()current确保拿到最新的状态
  • 当访问getter时才重新计算值result

react hook实现computed
http://yoursite.com/2022/06/06/react实现computed/
作者
tatekii
发布于
2022年6月6日
许可协议