React的useMemo Hook

178 阅读3分钟

在React的函数组件世界中,useMemo 是一个非常重要的 Hook,它用于优化性能,避免在组件的每次渲染中都执行昂贵的计算。

useMemo 的基本概念

useMemo 是一个React Hook,它返回一个缓存的值。这个值只会在其依赖项(dependencies)改变时才会重新计算。换句话说,如果 useMemo 的依赖项没有变化,那么它之前计算的结果将被重用,从而避免不必要的计算开销。

语法

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • 第一个参数是一个“创建”函数,它接收依赖项作为参数并返回一个值。
  • 第二个参数是一个依赖项数组,数组中的值决定了何时重新计算 memoizedValue

使用场景

1. 避免在渲染过程中执行昂贵的计算

如果你的组件中需要进行一些计算,而这些计算的结果在依赖项不变的情况下不会改变,那么可以使用 useMemo 来缓存这些计算结果。这样,即使组件重新渲染,只要依赖项没有变化,这些计算就不会再次执行。

2. 优化子组件的性能

当父组件向子组件传递大量数据或计算结果时,如果这些数据或结果在子组件的渲染过程中不会改变,那么使用 useMemo 可以避免在每次父组件渲染时都重新计算这些数据或结果,从而提高子组件的性能。

3. 减少渲染次数

在某些情况下,通过 useMemo 缓存的值可以作为其他Hooks(如useEffectuseCallback)的依赖项,从而减少不必要的副作用执行或回调函数创建。

注意事项

1. 不要过度使用

虽然 useMemo 可以提升性能,但过度使用可能会导致代码变得难以理解和维护。只有当计算确实昂贵且需要缓存时,才应该使用 useMemo

2. 依赖项的正确性

确保 useMemo 的依赖项数组包含了所有可能影响计算结果的变量。如果遗漏了某个依赖项,那么计算结果可能会在不应该的时候被重用,导致应用出现错误的行为。

3. 与 useCallback 的区别

useCallback 是 useMemo 的一个特例,它专门用于缓存函数。当你需要缓存一个函数,并且这个函数的创建依赖于某些值时,应该使用 useCallback。而当你需要缓存任何类型的值时(不仅仅是函数),则应该使用 useMemo

举例

import React, { useMemo, useState } from 'react'

function A(props) {
  return <div>A:{props.num}</div>
}
export default function App() {
  const [num, setNum] = useState(0)
  const [num1, setNum1] = useState(0)

  const onClick1 = () => {
    setNum1(num1 - 1)
  }

  const onClick = () => {
    setNum(num + 1)
  }

  return (
    <div>
      <A num={num1} />
      <div>APP:{num}</div>
      <button onClick={onClick}>增加</button>
      <button onClick={onClick1}>减少</button>
    </div>
  )
}

点击增加按钮,但是触发了子组件的渲染,但此时子组件没有任何更新

image.png

因此,可以利用useMemo来优化

import React, { useMemo, useState } from 'react'

function A(props) {
  return <div>A:{props.num}</div>
}
export default function App() {
  const [num, setNum] = useState(0)
  const [num1, setNum1] = useState(0)

  const onClick1 = () => {
    setNum1(num1 - 1)
  }

  const onClick = () => {
    setNum(num + 1)
  }

  const memoizedA = useMemo(() => {
    return <A num={num1} />
  }, [num1])

  return (
    <div>
      {memoizedA}
      <div>APP:{num}</div>
      <button onClick={onClick}>增加</button>
      <button onClick={onClick1}>减少</button>
    </div>
  )
}

结论

useMemo 是React中用于性能优化的强大工具。通过合理地使用 useMemo,我们可以避免在组件的每次渲染中都执行昂贵的计算,从而提高应用的性能。然而,我们也需要注意不要过度使用 useMemo,并确保正确地指定依赖项数组,以避免潜在的问题。