乐趣区

关于react.js:React-Hooks-系列-之-useMemo

React Hooks 系列 之 useMemo

  • 原文地址 –DapanDocs:https://skillgroup.cn/framework/react/hooks/use-memo.html

介绍

useMemo 是 React 的一个 Hook,它用于优化性能,特地是在组件从新渲染时。当组件的某些状态或属性发生变化时,useMemo 能够帮忙咱们防止不必要的计算或渲染。

在简单的 React 利用中,咱们可能会遇到组件频繁从新渲染的状况,这可能会导致利用性能降落。有时,即便状态或属性产生了变动,咱们也不心愿执行某些计算或渲染。这时,useMemo 就派上了用场。

useMemo 承受两个参数:一个函数和一个依赖数组。函数返回咱们想要“记住”的值,而依赖数组通知 React 什么时候从新计算这个值。

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

::: warning 留神
useMemo 第二个参数是一个数组,浅比拟数组中的值,如果是对象或者数组即比拟其援用是否产生了变动,如果有变动则从新计算,否则不从新计算。

案例能够参考 useEffect 中的依赖项。传送门:React Hooks 系列 之 useEffect
:::

用法

1、跳过代价低廉的从新计算

useMemo 返回一个 memoized 值。这意味着它会记住上一次的计算结果,并在依赖项没有发生变化时返回该后果,而不是从新计算。这能够帮忙防止在每次渲染时进行低廉的计算。

<div ref=”useMemo1″ />

::: details demo 代码
<<< @/components/react/hooks/useMemo/SkipExpensiveCalc.jsx
:::

在这个例子中,咱们能够通过比照三个按钮的行为来剖析 useMemo 的作用:

  1. 对于 ”maxKey – 100″ 按钮:点击该按钮会更新 maxKey 的值,因为没有应用 useMemo,所以只有有状态更新都会从新计算从 1 到maxKey 的数字之和并显示在页面上计算数字之和,即便 maxKey 的值没有发生变化。
  2. 对于 ”maxNumber – 100″ 按钮:点击该按钮会更新 maxNumber 的值,然而如果 maxNumber 没有发生变化,即点击前后的值雷同,那么应用了 useMemomaxNumberSum函数不会从新计算,而是返回之前缓存的后果。只有 maxNumber 发生变化时,maxNumberSum才须要从新计算。
  3. 对于 ”Count + 1″ 按钮:点击该按钮只会更新 count 的值,对 maxKeymaxNumber没有影响。maxNumberSum 函数不会从新计算,因为它的依赖项没有发生变化。maxKeySum 因为没有应用 useMemo,所以页面从新渲染时,maxKeySum 函数会从新执行。

综上所述,useMemo的作用是在依赖项发生变化时进行记忆优化,防止不必要的反复计算,进步性能。在本例中,咱们应用 useMemo 优化了从 1 到 maxNumber 的数字之和的计算,确保仅当 maxNumber 发生变化时才从新计算,防止了在每次渲染时都进行计算的开销。

2、跳过组件的从新渲染

useMemo的另一个用处是跳过组件的从新渲染。在某些状况下,咱们心愿组件的某些属性发生变化时,组件不会从新渲染。这时,咱们能够应用 useMemo 来返回组件的 memoized 值,从而防止组件的从新渲染。

<div ref=”useMemo2″ />

::: details demo 代码
<<< @/components/react/hooks/memo/ObjectInProps3.jsx
:::

调用 useMemo 后大抵执行状况

graph TD
    A[调用 useMemo]
    B[创立 / 获取以后组件的 Fiber 节点]
    C[查看 Fiber 节点上的 hooks 链表 - 每个节点对应一个 hook]
    D[是否存在对应的 hook 对象?]
    E[创立新的 hook 对象]
    F[查看 hook 对象的 memoizedState 属性]
    G[依赖项是否扭转?]
    H[从 memoizedState 获取值]
    I[从新计算值]
    J[更新 memoizedState 属性]
    K[返回 memoized 值]

    A --> B
    B --> C
    C --> D
    D -- No --> E
    D -- Yes --> F
    E --> F
    F --> G
    G -- No --> H --> K
    G -- Yes --> I --> J --> K
退出移动版