面试题答案
一键面试类组件中使用 shouldComponentUpdate
优化
- 原理:
shouldComponentUpdate(nextProps, nextState)
方法会在组件接收到新的 props 或 state 时被调用。返回true
表示组件需要重新渲染,返回false
表示不需要重新渲染。通过比较当前和下一个 props 与 state,决定是否重新渲染。 - 示例:
import React, { Component } from 'react';
class DynamicList extends Component {
shouldComponentUpdate(nextProps, nextState) {
// 简单比较 props 中的某个属性,假设列表数据在 props.items 中
if (this.props.items.length!== nextProps.items.length) {
return true;
}
// 或者更复杂的比较,比如比较列表项的某个属性
for (let i = 0; i < this.props.items.length; i++) {
if (this.props.items[i].id!== nextProps.items[i].id) {
return true;
}
}
return false;
}
render() {
return (
<ul>
{this.props.items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
}
export default DynamicList;
- 重新渲染情况:当
shouldComponentUpdate
返回true
时重新渲染。比如列表项数量改变,或者列表项的关键属性(如示例中的id
)改变时。 - 不重新渲染情况:当
shouldComponentUpdate
返回false
时不重新渲染。例如列表项的一些非关键属性改变,且shouldComponentUpdate
逻辑中未对此进行判断。
函数组件中使用 React.memo
优化
- 原理:
React.memo
是一个高阶组件,它对函数组件进行了浅比较优化。它会默认比较 props,若 props 没有变化,组件不会重新渲染。 - 示例:
import React from'react';
const DynamicList = React.memo(({ items }) => {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
});
export default DynamicList;
- 重新渲染情况:当 props 中的引用类型数据(如数组、对象)发生变化,即使内部数据实际未改变,也可能因为浅比较导致重新渲染。例如,创建了一个新的空数组作为 props 传递,即使数组内容和之前一样,组件也会重新渲染。
- 不重新渲染情况:当 props 没有变化,或者 props 中基本类型数据没有变化时,组件不会重新渲染。如果想对引用类型数据进行更深入的比较,可以传递第二个参数
areEqual
函数给React.memo
,自定义比较逻辑。例如:
import React from'react';
const areEqual = (prevProps, nextProps) => {
if (prevProps.items.length!== nextProps.items.length) {
return false;
}
for (let i = 0; i < prevProps.items.length; i++) {
if (prevProps.items[i].id!== nextProps.items[i].id) {
return false;
}
}
return true;
};
const DynamicList = React.memo(({ items }) => {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}, areEqual);
export default DynamicList;
这样只有当列表项的 id
等关键属性变化时才会重新渲染。