useCreation
作用
useCreation 是 useMemo 或 useRef 的替代品。
因为 useMemo 不能保证被 memo 的值一定不会被重计算,而 useCreation 可以保证这一点。以下为 React 官方文档中的介绍:
You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.
而相比于 useRef,你可以使用 useCreation 创建一些常量,这些常量和 useRef 创建出来的 ref 有很多使用场景上的相似,但对于复杂常量的创建,useRef 却容易出现潜在的性能隐患。
ts
const a = useRef(new Subject()) // 每次重渲染,都会执行实例化 Subject 的过程,即便这个实例立刻就被扔掉了
const b = useCreation(() => new Subject(), []) // 通过 factory 函数,可以避免性能隐患
原理
useCreation 的原理其实很简单,就是在 useRef 的基础上,增加了一个 initialized 参数,用于控制是否需要重新创建值。
源码
ts
import type { DependencyList } from 'react'
import { useRef } from 'react'
import depsAreSame from '../utils/depsAreSame'
export default function useCreation<T>(factory: () => T, deps: DependencyList) {
const { current } = useRef({
deps,
obj: undefined as undefined | T,
initialized: false,
})
//初始化或者依赖改变时,重新执行工厂函数
if (current.initialized === false || !depsAreSame(current.deps, deps)) {
// 更新依赖
current.deps = deps
// 执行工厂函数
current.obj = factory()
// 标记更改为已初始化
current.initialized = true
}
return current.obj as T
}