Advanced
useCreation
缓存计算量较大或创建成本较高的数据
用法
0.1523355367408621
源码
import type { DependencyList } from 'react';
import { useRef } from 'react';
import depsAreSame from '../utils/depsAreSame';
const useCreation = <T>(factory: () => T, deps: DependencyList) => {
const { current } = useRef({
deps,
obj: undefined as T,
initialized: false,
});
if (current.initialized === false || !depsAreSame(current.deps, deps)) {
current.deps = deps;
current.obj = factory();
current.initialized = true;
}
return current.obj;
};
export default useCreation;import type { DependencyList } from 'react';
function depsAreSame(oldDeps: DependencyList, deps: DependencyList): boolean {
if (oldDeps === deps) {
return true;
}
for (let i = 0; i < oldDeps.length; i++) {
if (!Object.is(oldDeps[i], deps[i])) {
return false;
}
}
return true;
}
export default depsAreSame;解读
先看 depsAreSame 函数,用于比较两个依赖数组是否相同,内部采用 Object.is 进行比较。
function depsAreSame(oldDeps: DependencyList, deps: DependencyList): boolean {
if (oldDeps === deps) {
return true;
}
for (let i = 0; i < oldDeps.length; i++) {
if (!Object.is(oldDeps[i], deps[i])) {
return false;
}
}
return true;
}而 useCreation 函数则是在内部使用 useRef 定义了一个 ref 对象,用于存储依赖数组和计算结果。
const useCreation = <T>(factory: () => T, deps: DependencyList) => {
// 1. 定义一个 ref 对象,用于存储依赖数组和计算结果
const { current } = useRef({
deps,
obj: undefined as T,
initialized: false,
});
// 2. 如果依赖数组未初始化,或者依赖数组发生变化,则更新依赖数组并重新计算结果
if (current.initialized === false || !depsAreSame(current.deps, deps)) {
// 2.1. 更新依赖数组
current.deps = deps;
// 2.2. 重新计算结果
current.obj = factory();
// 2.3. 标记为已初始化
current.initialized = true;
}
// 3. 返回计算结果
return current.obj;
};Last updated on