“说一下memo和useMemo” "啥?这不是同一个东西吗" “回去等通知吧”
前记
实不相瞒,这是很久之前面试的碰到的一个问题,现在半夜都想起来给自己两巴掌。然后时不时还是会想到这个问题,我靠,真的好尬,在简历上写着熟悉React,然后说出那么清新脱俗的答案,所以今天决定整理下来,下次再战!
memo和useMemo的区别
直接上两者的区别,直捣黄龙!
- 用途不同:
memo是一个高阶组件,用于优化函数组件的渲染性能,会对组件的props进行浅比较,只有在props发生变化时才重新渲染组件;
useMemo是一个Hook,用于在函数组件内部进行记忆计算,它会缓存结果,只有在依赖项变化时才重新计算.
- 参数不同
memo接受两个参数,第一个参数是需要被优化的组件,第二个参数是一个自定义的比较函数,用于决定何时重新渲染组件;
useMemo接受两个参数,第一个参数是一个函数,用于进行计算,第二个参数是一个依赖数组,只有当依赖项发生变化时,才会重新计算并返回新的计算结果。
- 返回值不同
memo返回一个新的优化后的组件,当组件的props没有变化时,会返回上一次的渲染结果;
useMemo返回缓存的计算结果。
- 使用场景不同:
memo的使用场景:
- 当组件的
props较为复杂或计算开销较大时,可以使用memo来优化组件的渲染性能。通过memo包装组件,只有在props发生变化时,才会重新渲染组件。 - 当函数组件的渲染结果只依赖于
props时,可以使用memo来避免不必要的重新渲染。这适用于那些没有内部状态或副作用的纯展示组件。
useMemo的使用场景:
- 当需要在函数组件内部进行记忆化计算时,可以使用
useMemo。通过缓存计算结果,可以避免重复计算相同的结果,提高性能。 - 当需要对计算结果进行缓存,并在依赖项发生变化时重新计算时,可以使用
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 的原理
memo和useMemo的原理是基于数据的缓存和依赖项的比较来进行性能优化。
对于memo,它会对组件的props进行浅比较。当组件的props没有发生变化时,memo会返回上一次的渲染结果,而不重新渲染组件。这是因为浅比较可以快速比较对象的引用是否相同,如果引用相同,则可以认为对象没有变化。
对于useMemo,它接受一个计算函数和一个依赖项数组。在首次渲染或依赖项发生变化时,useMemo会调用计算函数,并缓存计算结果。在后续的渲染中,如果依赖项没有发生变化,useMemo会直接返回缓存的计算结果,避免重复计算。
useMemo的原理是基于缓存和依赖项的比较。当依赖项发生变化时,useMemo会重新计算并返回新的计算结果,同时更新缓存。如果依赖项没有发生变化,则直接返回缓存的计算结果。