“说一下memo和useMemo” "啥?这不是同一个东西吗" “回去等通知吧”

167 阅读4分钟

“说一下memo和useMemo” "啥?这不是同一个东西吗" “回去等通知吧”

前记

实不相瞒,这是很久之前面试的碰到的一个问题,现在半夜都想起来给自己两巴掌。然后时不时还是会想到这个问题,我靠,真的好尬,在简历上写着熟悉React,然后说出那么清新脱俗的答案,所以今天决定整理下来,下次再战!

memo和useMemo的区别

直接上两者的区别,直捣黄龙!

  • 用途不同:

memo是一个高阶组件,用于优化函数组件的渲染性能,会对组件的props进行浅比较,只有在props发生变化时才重新渲染组件;

useMemo是一个Hook用于在函数组件内部进行记忆计算,它会缓存结果,只有在依赖项变化时才重新计算.

  • 参数不同

memo接受两个参数,第一个参数是需要被优化的组件,第二个参数是一个自定义的比较函数,用于决定何时重新渲染组件;

useMemo接受两个参数,第一个参数是一个函数,用于进行计算,第二个参数是一个依赖数组,只有当依赖项发生变化时,才会重新计算并返回新的计算结果。

  • 返回值不同

memo返回一个新的优化后的组件,当组件的props没有变化时,会返回上一次的渲染结果

useMemo返回缓存的计算结果

  • 使用场景不同:

memo的使用场景:

  1. 当组件的props较为复杂或计算开销较大时,可以使用memo来优化组件的渲染性能。通过memo包装组件,只有在props发生变化时,才会重新渲染组件。
  2. 当函数组件的渲染结果只依赖于props时,可以使用memo来避免不必要的重新渲染。这适用于那些没有内部状态或副作用的纯展示组件。

useMemo的使用场景:

  1. 当需要在函数组件内部进行记忆化计算时,可以使用useMemo。通过缓存计算结果,可以避免重复计算相同的结果,提高性能。
  2. 当需要对计算结果进行缓存,并在依赖项发生变化时重新计算时,可以使用useMemo。这对于那些计算开销较大,但只在特定条件下需要进行计算的情况很有用。

memo和useMemo的代码例子

上代码!

  • 使用memo优化组件的渲染性能:
import React, { memo } from 'react';

// 普通函数组件
const MyComponent = ({ name }) => {
  console.log('Rendering MyComponent');
  return <div>{name}</div>;
};

// 使用memo包装组件
const MemoizedComponent = memo(MyComponent);

// 使用MemoizedComponent作为组件使用
const App = () => {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <MemoizedComponent name="John" />
    </div>
  );
};

在上面的例子中,MyComponent是一个普通的函数组件。通过使用memo将其包装成MemoizedComponent,只有当name发生变化时,MemoizedComponent才会重新渲染,避免了不必要的渲染。

  • 使用useMemo进行记忆化计算:
import React, { useMemo } from 'react';

const ExpensiveCalculation = ({ number }) => {
  console.log('Performing expensive calculation');
  // 模拟一个昂贵的计算过程
  const result = useMemo(() => {
    let sum = 0;
    for (let i = 1; i <= number; i++) {
      sum += i;
    }
    return sum;
  }, [number]);

  return <div>{result}</div>;
};

const App = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <ExpensiveCalculation number={count} />
    </div>
  );
};

在上面的例子中,ExpensiveCalculation组件进行了一个昂贵的计算,通过使用useMemo来缓存计算结果,只有当number发生变化时,才会重新进行计算。这样可以避免在每次渲染时都进行重复的计算。

memo 和 useMemo 的原理

memouseMemo的原理是基于数据的缓存和依赖项的比较来进行性能优化

对于memo,它会对组件的props进行浅比较。当组件的props没有发生变化时,memo会返回上一次的渲染结果,而不重新渲染组件。这是因为浅比较可以快速比较对象的引用是否相同,如果引用相同,则可以认为对象没有变化。

对于useMemo,它接受一个计算函数和一个依赖项数组。在首次渲染或依赖项发生变化时,useMemo会调用计算函数,并缓存计算结果。在后续的渲染中,如果依赖项没有发生变化,useMemo会直接返回缓存的计算结果,避免重复计算。

useMemo的原理是基于缓存和依赖项的比较。当依赖项发生变化时,useMemo会重新计算并返回新的计算结果,同时更新缓存。如果依赖项没有发生变化,则直接返回缓存的计算结果。

好好学习