自定义Hook返回useCallback创建的函数时,是否需使用useMemo?
在自定义Hook中使用useMemo包裹返回值的判断依据
针对你给出的useBooleanState Hook,要不要用useMemo包裹返回值,核心看这个Hook的使用场景,分两种情况说明:
不需要加useMemo的场景
如果这个Hook的返回值只是在组件内部直接使用(比如直接调用setTrue、读取value),既没有作为useEffect/useCallback等Hook的依赖项,也没有传递给用React.memo包裹的子组件,那完全没必要加useMemo。
原因很简单:每次组件重渲染时,创建一个新的对象字面量的开销微乎其微,反而useMemo本身需要对比依赖数组、维护缓存值,会带来额外的性能消耗,属于过度优化。
需要加useMemo的场景
如果存在以下两种情况,就应该用useMemo稳定返回对象的引用:
- 作为其他Hook的依赖:比如你把整个返回对象放到
useEffect的依赖数组里:
不加useMemo的话,哪怕const boolState = useBooleanState(); useEffect(() => { console.log("状态相关操作"); }, [boolState]);value没变化,每次组件重渲染都会生成新的boolState对象,导致useEffect被频繁触发,这时候用useMemo就能避免这种不必要的执行。 - 传递给memo化的子组件:如果把返回对象作为props传给用
React.memo包裹的子组件:
不加useMemo的话,父组件每次重渲染都会传递新的对象引用,导致const MemoizedChild = React.memo(ChildComponent); // ... <MemoizedChild state={useBooleanState()} />React.memo的浅比较失效,子组件会被不必要地重渲染,这时候useMemo能稳定引用,让memo生效。
另外补充个小细节:你Hook里的setValue是useState返回的 setter 函数,React保证它的引用在组件生命周期内是稳定的,所以你可以把useCallback里的依赖数组[setValue]去掉,这样setTrue、setFalse、toggle的引用会更稳定,进一步减少useMemo的触发次数。
内容的提问来源于stack exchange,提问作者Danilo Cunha
相关产品推荐
相关产品推荐

