usememo与usecalkback区别

82 阅读3分钟

useMemo 和 useCallback 都是 React 中用来优化性能的钩子,尽管它们看起来相似,但它们的用途和行为有所不同。下面详细解释这两个钩子的区别。

  1. useMemo 和 useCallback 的基本区别 • useMemo 用来缓存某个计算值,确保只有在依赖项变化时才重新计算这个值。 • useCallback 用来缓存一个函数实例,确保只有在依赖项变化时才会重新创建这个函数。

  2. 具体用途 • useMemo: • 用于缓存计算结果,防止每次渲染都重新执行一些开销大的计算操作。 • 返回值是计算后的值。 例子:

const computedValue = useMemo(() => { return expensiveCalculation(a, b); }, [a, b]);

在这个例子中,只有当 a 或 b 改变时,expensiveCalculation(a, b) 才会重新执行,否则返回上次计算的结果。

•	useCallback:
•	用于缓存函数实例,防止每次渲染都创建新的函数实例,通常用于传递给子组件的回调函数,避免不必要的渲染。
•	返回值是一个函数。

例子:

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

在这个例子中,doSomething(a, b) 只会在 a 或 b 改变时重新创建 memoizedCallback,否则返回上次缓存的函数实例。

  1. 工作机制 • useMemo: • 只有当依赖项发生变化时,useMemo 会重新计算并返回新的值。如果依赖项不变化,它会返回上一次缓存的结果。 • 适用于 开销较大的计算。 • useCallback: • 只有当依赖项发生变化时,useCallback 才会返回一个新的函数实例。否则,它会返回上一次缓存的函数。 • 适用于 避免传递新的函数实例 给子组件,防止不必要的重新渲染。

  2. 使用场景 • useMemo: • 用于缓存计算的值,以提高性能,尤其是当计算开销较大时。 • 示例:数据处理、过滤、排序等。 • useCallback: • 用于缓存函数实例,防止在每次渲染时都重新创建函数。尤其是在传递回调函数给子组件时,如果不使用 useCallback,子组件可能会因为函数的引用变化而重新渲染。 • 示例:避免父组件多次传递新的回调函数给子组件。

  3. 性能优化角度 • useMemo:缓存的是计算结果,目的是避免重复执行昂贵的计算。 • useCallback:缓存的是函数实例,目的是避免重复创建函数,尤其是在传递给子组件时,避免因函数引用变化导致子组件不必要的重新渲染。

  4. 例子比较

useMemo 示例:

const filteredList = useMemo(() => { return list.filter(item => item.isActive); }, [list]);

这个例子中,只有当 list 改变时,才会重新计算 filteredList,否则返回上次的计算结果。

useCallback 示例:

const handleClick = useCallback(() => { console.log('Button clicked'); }, []);

这个例子中,handleClick 函数在第一次渲染时创建并缓存,以后每次渲染时,如果依赖项(空数组)没有变化,就不会重新创建该函数,防止子组件因回调函数的变化而重新渲染。

  1. 小结

特性 useMemo useCallback 返回值 缓存的计算值 缓存的函数实例 用途 缓存计算的结果,优化性能 缓存函数实例,防止多次创建相同的函数 依赖项 只有在依赖项变化时才重新计算缓存的值 只有在依赖项变化时才返回新的函数实例 使用场景 当计算值非常昂贵时,避免重复计算 当将函数传递给子组件时,避免创建新函数

总结来说,useMemo 是用于缓存计算值的,而 useCallback 是用于缓存函数实例的。两者都帮助我们避免不必要的计算或函数创建,从而提高组件的性能。