useMemo和useCallback的区别和使用

useMemo

 

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

将“创建”函数和依赖项添加到参数上使用备注,它仅会在某个依赖项改变时才重新计算备忘录值。这种优化避免在每次渲染时都进行高开销的计算。

也就是说useMemo可以让函数在某个依赖项改变的时候才运行,这可以避免很多额外的开销。举个例子:

不使用useMemo

复制代码
function Example() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
 
    const getNum = useMemo(() => {
        return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
    }, [count])
 
    return <div>
        <h4>总和:{getNum()}</h4>
        <div>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}
复制代码

使用useMemo后,成为count作为依赖值传递进去,此时仅count变化时才会重新执行getNum

useCallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

将内联变量函数和依赖项替换为参数回调使用,回调返回该变量函数的备注,版本,该变量函数仅在某个依赖项改变时才会更新。当您将函数传递给经过优化的并使用引用替代性去避免非必要渲染(例如shouldComponentUpdate)的子组件时,则非常有用。


看起来似乎和useMemo差不多,我们来看看这两个有什么异同:


useMemouseCallback接收的参数都是一样,都是在其依赖项发生变化后才执行,都是返回缓存的值,区别在于useMemo返回的是函数运行的结果,useCallback返回的是函数。

useCallback(fn,deps)相当于useMemo(()=> fn,deps)

使用场景
顶部上面所说的,当你把某些函数传递给经过优化的并使用引用替代性去避免非必要渲染(例如shouldComponentUpdate)的子组件时,则非常有用。而父组件传递一个函数给子组件的时候,由于父组件的更新会导致该函数重新生成从而传递给子组件的函数引用发生了变化,这就会导致子组件也会更新,而很多时候子组件的更新是没必要的,所以我们可以通过useCallback来缓存该函数,然后传递给子组件。举个例子:

复制代码
function Parent() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
 
    const getNum = useCallback(() => {
        return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
    }, [count])
 
    return <div>
        <Child getNum={getNum} />
        <div>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}

const Child = React.memo(function ({ getNum }: any) {
    return <h4>总和:{getNum()}</h4>
})
复制代码

使用useCallback之后,仅当count发生变化时Child组件才会重新渲染,而val变化时,Child组件是不会重新渲染的。

作者:威少_zv
链接:https://www.jianshu.com/p/b71e56ea2fda
来源:简书

 

posted @   6NULL9  阅读(5127)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示