返回

React · 揭秘 useMemo & useCallback 的妙用,掌握 Hooks 的精髓

前端

前言

默认情况下,父组件的状态 (state) 发生变化时,不仅会重新渲染自己,还会重新渲染其子组件。这种情况在一些场景下可能会导致性能问题,特别是当子组件很复杂或计算量很大时。为了解决这个问题,React 发明了 useMemo 和 useCallback 来帮助你减少不必要的渲染。

一、useMemo 详解

useMemo 允许你在函数组件中缓存一个值,该值只会在其依赖项发生变化时才重新计算。这对于一些计算量很大的函数非常有用,可以显著提升性能。

1. 语法

const memoizedValue = useMemo(() => expensiveComputation(props), [props]);

其中:

  • expensiveComputation 是一个纯函数,它会返回一个值。
  • props 是 memoizedValue 依赖的 props。

2. 原理

useMemo 会在组件首次渲染时调用 expensiveComputation 函数,并将结果存储在 memoizedValue 中。在随后的渲染中,useMemo 会比较 memoizedValue 的依赖项 (props) 是否发生变化。如果依赖项没有变化,useMemo 就会直接返回 memoizedValue,而不会重新调用 expensiveComputation 函数。

3. 使用场景

useMemo 可以用于以下场景:

  • 缓存一些计算量很大的值,例如一个复杂的函数或一个大型数组的过滤结果。
  • 缓存一些需要从外部 API 获取的数据,例如用户数据或产品列表。
  • 缓存一些需要进行复杂计算的组件的子树,例如一个带有复杂逻辑的表单。

二、useCallback 详解

useCallback 允许你在函数组件中缓存一个函数,该函数只会在其依赖项发生变化时才重新创建。这对于一些需要在组件中多次调用的函数非常有用,可以减少不必要的函数创建,并提升性能。

1. 语法

const memoizedCallback = useCallback(() => {
  // Do something
}, [props]);

其中:

  • memoizedCallback 是一个 memoized 的回调函数。
  • props 是 memoizedCallback 依赖的 props。

2. 原理

useCallback 会在组件首次渲染时创建一个 memoizedCallback 函数,并将它存储在内存中。在随后的渲染中,useCallback 会比较 memoizedCallback 的依赖项 (props) 是否发生变化。如果依赖项没有变化,useCallback 就会直接返回 memoizedCallback,而不会重新创建它。

3. 使用场景

useCallback 可以用于以下场景:

  • 缓存一些需要在组件中多次调用的函数,例如一个事件处理函数或一个计时器函数。
  • 缓存一些需要传递给子组件的函数,例如一个更新子组件状态的函数或一个控制子组件行为的函数。
  • 缓存一些需要在组件中多次调用的复杂逻辑,例如一个表单验证函数或一个数据处理函数。

三、useMemo 与 useCallback 的区别

useMemo 和 useCallback 都是 React 提供的 Hooks,它们都用于优化组件的性能。但它们之间还是有一些区别的:

  • useMemo 用于缓存一个值,而 useCallback 用于缓存一个函数。
  • useMemo 只会在其依赖项发生变化时重新计算,而 useCallback 只会在其依赖项发生变化时重新创建。
  • useMemo 通常用于缓存一些计算量很大的值,而 useCallback 通常用于缓存一些需要在组件中多次调用的函数。

四、总结

useMemo 和 useCallback 是 React 中非常有用的两个 Hooks,它们可以帮助你减少不必要的渲染和函数创建,从而提升组件的性能。在使用它们时,需要注意以下几点:

  • useMemo 和 useCallback 只能在函数组件中使用。
  • useMemo 和 useCallback 都是纯函数,这意味着它们不会修改组件的状态或产生副作用。
  • useMemo 和 useCallback 可以嵌套使用。
  • useMemo 和 useCallback 可以与其他 Hooks 一起使用,例如 useEffect 和 useState。