React.memo
是 React 提供的一个高阶组件,用于性能优化。它类似于类组件中的 shouldComponentUpdate
,但适用于函数组件。React.memo
可以避免不必要的组件重新渲染,提高性能。
import React from 'react';
// 函数组件
const Component = ({ name }) => {
return (
<div>
Hi, {name}!
</div>
);
};
// 使用 React.memo 包装组件
const ComponentTwo= React.memo(Component);
// 在父组件中使用 ComponentTwo
const ParentComponent = () => {
const [count, setCount] = React.useState(0);
const handleButtonClick = () => {
setCount(count + 1);
};
return (
<div>
<ComponentTwo name="John" />
<button onClick={handleButtonClick}>Increment Count</button>
</div>
);
};
export default ParentComponent;
在上面的示例中,Component
是一个简单的函数组件,而 ComponentTwo
是通过 React.memo
包装的组件。当 ParentComponent
中的状态更新时,Component
会被重新渲染,但由于被 React.memo
包装,ComponentTwo
只有在 name
发生变化时才会重新渲染。
通过使用 React.memo
,可以确保组件仅在其 props 发生变化时重新渲染,从而提高性能,特别是在有大量组件需要渲染时。
更加精确的渲染(react.memo的深比较):
React.memo
默认使用浅比较(shallow comparison)来确定是否重新渲染组件。这意味着它只会比较 props 对象的引用,而不会深度比较对象内部的值。如果你的组件接收复杂对象作为 props,而这些对象的引用未发生变化,React.memo
可能会误认为组件的 props 没有变化,从而避免重新渲染。
如果需要进行深比较,可以使用 React.memo
的第二个参数,该参数是一个比较函数。比较函数接收两个参数:先前的 props 和新的 props,如果函数返回 true
,则表示 props 没有变化,组件不会重新渲染;如果返回 false
,则表示 props 发生了变化,组件会重新渲染。
import React from 'react';
const areEqual = (prevProps, nextProps) => {
// 比较 props 对象内部的值
return (
prevProps.name === nextProps.name &&
prevProps.age === nextProps.age
// 继续添加其他需要比较的属性或直接使用lodash及其他便捷的深比较方法
);
};
const MyComponent = ({ name, age }) => {
console.log('Rendering MyComponent');
return (
<div>
{name}, {age} years old
</div>
);
};
// 使用 React.memo 并传入比较函数
const MemoizedComponent = React.memo(MyComponent, areEqual);
const ParentComponent = () => {
const [person, setPerson] = React.useState({ name: 'John', age: 30 });
const handleButtonClick = () => {
// 创建新的对象,但属性值相同
setPerson({ ...person });
};
return (
<div>
<MemoizedComponent name={person.name} age={person.age} />
<button onClick={handleButtonClick}>Update Props</button>
</div>
);
};
export default ParentComponent;
areEqual
函数负责比较 MyComponent
的 name
和 age
属性。如果这些属性的值在两个 props 对象中相等,那么 React.memo
将避免重新渲染组件。这种方式可以实现对复杂对象进行深比较,确保只有对象内部值发生变化时才触发重新渲染。(深比较函数可以采用其他更加便捷的比较方式,可参考监听引用数据类型变化的方法-CSDN博客)