React.memo()
和 React.useMemo()
是 React 中用于优化性能的两个工具,但它们的用途和实现方式有所不同。以下分别介绍它们的用法和区别。
1. React.memo()
用法
React.memo()
是一个高阶组件(HOC),由于react组件默认的渲染机制:只要父组件渲染子组件就会重新渲染
于是用于优化函数组件的渲染性能。它通过缓存组件的渲染结果,避免不必要的重新渲染。
作用
允许组件在Prop 没有改变的情况下跳过渲染
基本语法:
const MemoizedComponent = React.memo(FunctionComponent);
带比较函数的用法:
const MemoizedComponent = React.memo(FunctionComponent, arePropsEqual);
其中,
arePropsEqual
是一个比较函数,在使用memo缓存组件之后,react 会对每一个prop 使用Object.is 比较新值和老值 用于比较新旧 props 是否相等。如果返回true
,则组件不会重新渲染。
示例
import React from 'react';
const MyComponent = ({ name }) => {
console.log('Rendering MyComponent');
return <div>Hello, {name}</div>;
};
const MemoizedComponent = React.memo(MyComponent);
const App = () => {
const [count, setCount] = React.useState(0);
return (
<div>
<MemoizedComponent name="Alice" />
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default App;
在这个例子中,MemoizedComponent
只会在 name
属性发生变化时重新渲染,而不会因为 count
的变化而重新渲染。
注意事项
React.memo()
只对组件的 props 进行浅比较。如果需要更复杂的比较逻辑,可以通过arePropsEqual
函数来实现。- 它只适用于函数组件,不适用于类组件。
- 它不会影响子组件的渲染行为,子组件仍然会根据自己的 props 或 state 变化而重新渲染。
2. React.useMemo()
用法
React.useMemo()
是一个 Hook,用于缓存计算结果,避免在组件重新渲染时重复计算。它通常用于优化性能,尤其是在计算复杂或耗时的场景中。
基本语法:
const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);
其中,
computeExpensiveValue
是一个计算函数,[a, b]
是依赖数组,当依赖数组中的值发生变化时,才会重新计算。
示例
import React, { useState, useMemo } from 'react';
const App = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
const expensiveCalculation = (num) => {
console.log('Calculating...');
return num * 2;
};
const memoizedValue = useMemo(() => expensiveCalculation(count), [count]);
return (
<div>
<p>{`Name: ${name}`}</p>
<p>{`Count: ${count}`}</p>
<p>{`Memoized Value: ${memoizedValue}`}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setName('Alice')}>Change Name</button>
</div>
);
};
export default App;
在这个例子中,expensiveCalculation
只会在 count
发生变化时重新计算,而不会因为 name
的变化而重新计算。
注意事项
useMemo
的依赖数组非常重要。如果依赖数组为空([]
),则计算结果只会计算一次,类似于useEffect
的空依赖数组。- 如果依赖数组中的值发生变化,
useMemo
会重新计算并返回新的值。 useMemo
并不会阻止组件的重新渲染,它只是缓存计算结果,减少不必要的计算。
区别
特性 | React.memo() | React.useMemo() |
---|---|---|
用途 | 优化组件渲染性能,避免不必要的重新渲染 | 优化计算性能,缓存计算结果 |
适用对象 | 函数组件 | 函数组件内的计算逻辑 |
实现方式 | 高阶组件(HOC),通过比较 props 来决定是否重新渲染 | Hook,通过缓存计算结果来避免重复计算 |
依赖数组 | 可选的 arePropsEqual 函数,用于自定义 props 比较逻辑 |
必须提供依赖数组,依赖数组中的值变化时重新计算 |
性能优化目标 | 避免组件的无意义渲染,减少 DOM 操作 | 避免重复计算,减少 CPU 资源消耗 |
使用场景 | 组件的 props 没有变化时,避免组件重新渲染 | 组件内的复杂计算逻辑,避免每次渲染都重新计算 |
总结
- 使用
React.memo()
来优化组件的渲染性能,尤其是当组件的 props 没有变化时,避免不必要的重新渲染。 - 使用
React.useMemo()
来优化组件内的计算逻辑,避免重复计算,尤其是在计算复杂或耗时的场景中。
根据具体的性能优化需求,选择合适的工具来提升应用的性能。