前言
React 中的这两个函数都带有 memo,看着比较相似,但是作用和使用场景却不一致。
memo 的英文含义为备忘录,可以理解为保存,记忆之类,从字面意思可以猜测到它的作用。
可能没有实战的童鞋还容易把这两个搞混,但是这两个函数有着完全不一样的功能,也不需要拿来比较,千万不要搞混了,今天就带大家一起来详细的分析一下这两个函数的作用和使用场景!
useMemo
useMemo 是 React 中用来进行性能优化的钩子函数之一,它的作用是用来缓存计算结果,只有在依赖项发生变化时才重新计算,可以有效减少不必要的计算开销。常见的使用场景是在需要进行大量计算或者复杂逻辑的组件中,通过 useMemo 缓存计算结果,避免不必要的重复计算,可以提高组件的性能。
当点击按钮时,count 会加1,而使用 useMemo 则会监听到依赖项的变化,此时会计算得到doubledCount,熟悉 Vue 的小伙伴应该会知道,和 computed 相似。
js
import React, { useState, useMemo } from 'react';
const App = () => {
const [count, setCount] = useState(0);
// 通过 useMemo 缓存计算结果
const doubledCount = useMemo(() => {
return count * 2;
}, [count]);
return (
<div>
<h1>useMemo Example</h1>
<p>Count: {count}</p>
<p>Doubled Count: {doubledCount}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
</div>
);
};
export default App;
React.memo
使用 React
的小伙伴都了解,当组件中的 state 数据发生变化
时,会重新渲染该组件,如果引入子组件,子组件也会重新渲染,这会造成不必要的开销。React.memo 则是用来解决这个问题的。
作用
React.memo
会浅比较当前组件的 props
与上一次渲染时的 props
。如果 props
没有变化,则跳过渲染过程。
在这个案例中,我们有两个点击事件,其中点击 handleChangeCount
会引起 count 的改变,当 count 改变时,会引起组件重新渲染,在组件中引入了子组件 MyComponent
,默认情况下 MyComponent 也会重新渲染。
很明显我们可以发现,MyComponent 里面并没有用到 count
,也就是说 MyComponent 组件并不需要重新渲染
,MyComponent 只需要在自己依赖
的 props 改变时重新渲染,所以我们使用 React.memo 进行包裹,包裹之后只会在 props 发生变化时重新渲染 MyComponent 组件 。
js
import React, { useState } from 'react';
// 一个纯函数组件
const MyComponent = React.memo(({ name, age }) => {
console.log('MyComponent rendered');
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
</div>
);
});
const App = () => {
const [person, setPerson] = useState({ name: 'John', age: 30 });
const [count, setCount] = useState(0);
const handleChangeAge = () => {
setPerson({ ...person, age: person.age + 1 });
};
const handleChangeCount = () => {
setCount(count + 1);
};
return (
<div>
<MyComponent name={person.name} age={person.age} />
<button onClick={handleChangeAge}>Change Age</button>
<button onClick={handleChangeCount}>Change Count</button>
<p>Count: {count}</p>
</div>
);
};
export default App;
通过使用 React.memo,
我们避免了 MyComponent
在不必要的情况下重新渲染,从而提高了性能。
需要注意的是,React.memo
只会对函数组件进行浅层
比较。如果 props
是一个引用类型(如对象或数组),即使属性值没有改变,React 也会认为它是一个新的引用,从而导致组件重新渲染。在这种情况下,可以使用 React.memo
的第二个参数来提供一个自定义的比较函数。
通过自定义第二个参数,拿到前一个跟后一个 props,从而比较里面的属性值
是否发生变化
而决定是否重新渲染组件。
js
import React from 'react';
const Person = React.memo(({ person }) => {
console.log('Person component rendered');
return (
<div>
<h2>{person.name}</h2>
<p>Age: {person.age}</p>
</div>
);
}, (prevProps, nextProps) => {
// 自定义比较函数
const prevPerson = prevProps.person;
const nextPerson = nextProps.person;
// 比较 person 对象的属性值
return (
prevPerson.name === nextPerson.name &&
prevPerson.age === nextPerson.age
);
});
const App = () => {
const [person, setPerson] = React.useState({ name: 'John', age: 30 });
const handleChangeAge = () => {
setPerson({ ...person, age: person.age + 1 });
};
return (
<div>
<Person person={person} />
<button onClick={handleChangeAge}>Change Age</button>
</div>
);
};
export default App;