面试题答案
一键面试1. shouldComponentUpdate
- 应用场景:在类组件中,用于控制组件是否需要重新渲染。当组件的props或state发生变化时,React会调用该方法。如果返回true,组件将重新渲染;返回false,则不会重新渲染。
- 实际优化方法:通过比较新老props和state,仅在有必要时返回true。例如,对于一个展示用户信息的组件,只有当用户信息(props中的数据)真正改变时才重新渲染。
class UserInfo extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return nextProps.user.name!== this.props.user.name || nextProps.user.age!== this.props.user.age;
}
render() {
return (
<div>
<p>Name: {this.props.user.name}</p>
<p>Age: {this.props.user.age}</p>
</div>
);
}
}
2. memo
- 应用场景:用于函数组件,功能类似于类组件中的shouldComponentUpdate。它会对组件的props进行浅比较,如果props没有变化,组件将不会重新渲染。
- 实际优化方法:直接包裹函数组件。例如,有一个展示静态内容的子组件:
const StaticContent = React.memo((props) => {
return <p>{props.text}</p>;
});
3. useCallback
- 应用场景:用于缓存函数,当依赖项没有变化时,返回相同的函数引用。常用于将回调函数传递给子组件,避免子组件因父组件重新渲染导致不必要的重新渲染。
- 实际优化方法:定义回调函数时使用useCallback。比如在一个列表组件中,点击列表项触发一个函数:
import React, { useCallback } from'react';
const List = () => {
const handleClick = useCallback(() => {
console.log('Item clicked');
}, []);
return (
<ul>
<li onClick={handleClick}>Item 1</li>
<li onClick={handleClick}>Item 2</li>
</ul>
);
};
4. useMemo
- 应用场景:用于缓存计算结果,只有当依赖项发生变化时,才重新计算。适用于一些开销较大的计算。
- 实际优化方法:比如计算一个数组中所有数字的总和:
import React, { useMemo } from'react';
const BigCalculation = ({ numbers }) => {
const sum = useMemo(() => {
return numbers.reduce((acc, num) => acc + num, 0);
}, [numbers]);
return <p>The sum is: {sum}</p>;
};
实际项目案例
在一个电商项目中,有一个商品列表页面,每个商品项是一个复合组件。商品列表会频繁地根据用户筛选条件进行重新渲染。
- 问题:当筛选条件变化时,即使单个商品的信息没有改变,每个商品组件也会重新渲染,导致性能下降。
- 解决方案:
- 对于商品展示组件,使用React.memo包裹,因为商品的展示主要依赖于props中的商品信息,浅比较props即可。
- 商品列表的筛选回调函数使用useCallback缓存,避免因父组件重新渲染导致回调函数引用变化,进而避免商品列表子组件不必要的重新渲染。
- 计算商品总价等开销较大的操作使用useMemo,只有当商品列表数据变化时才重新计算。通过这些优化策略,大大提升了商品列表页面的性能,减少了不必要的渲染,提高了用户体验。