面试题答案
一键面试避免不必要的重渲染
- 使用
React.memo
:React.memo
是一个高阶组件,它可以对函数组件进行浅比较。如果组件的 props 没有变化,它就不会重新渲染。- 例如,有一个展示用户信息的组件
UserInfo
:
const UserInfo = React.memo(({ user }) => {
return (
<div>
<p>{user.name}</p>
<p>{user.age}</p>
</div>
);
});
- 当
UserInfo
组件的父组件重新渲染,但user
prop 没有变化时,UserInfo
组件不会重新渲染。
- 拆分组件:
- 将大组件拆分成多个小组件,每个小组件只关心自己的数据。这样当某个数据变化时,只有相关的小组件会重新渲染。
- 比如在一个电商产品详情页面,将产品图片展示、产品描述、价格等部分拆分成不同组件。当产品价格变化时,只有价格组件会重新渲染。
const ProductImage = ({ imageUrl }) => {
return <img src={imageUrl} alt="product" />;
};
const ProductDescription = ({ description }) => {
return <p>{description}</p>;
};
const ProductPrice = ({ price }) => {
return <p>{price}</p>;
};
const ProductDetail = ({ product }) => {
return (
<div>
<ProductImage imageUrl={product.imageUrl} />
<ProductDescription description={product.description} />
<ProductPrice price={product.price} />
</div>
);
};
高效利用缓存机制
- 使用
useMemo
:useMemo
可以缓存一个值,只有当依赖项发生变化时才会重新计算。- 例如,在条件渲染中可能有复杂的计算:
const calculateComplexValue = (a, b) => {
// 复杂计算逻辑
return a + b;
};
const MyComponent = ({ a, b }) => {
const complexValue = useMemo(() => calculateComplexValue(a, b), [a, b]);
return (
<div>
{complexValue > 10 && <p>The value is greater than 10</p>}
</div>
);
};
- 这里
complexValue
只有在a
或b
变化时才会重新计算,避免了每次渲染都进行复杂计算。
- 使用
useCallback
:useCallback
可以缓存一个函数,同样只有当依赖项变化时才会重新创建函数。这在将函数作为 prop 传递给子组件时很有用,避免子组件因函数引用变化而不必要地重新渲染。- 例如:
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
const Button = ({ onClick }) => {
return <button onClick={onClick}>Click me</button>;
};
const ParentComponent = () => {
return (
<div>
<Button onClick={handleClick} />
</div>
);
};
- 这里
handleClick
函数引用不会在每次ParentComponent
渲染时变化,Button
组件也就不会因为函数引用变化而重新渲染。
实际项目中的落地策略
在一个在线教育平台项目中,有一个课程详情页面。课程详情包含课程介绍、讲师信息、学员评价等部分。
- 避免不必要重渲染:
- 对于讲师信息展示组件,使用
React.memo
进行包裹。因为讲师信息在课程详情页面打开后基本不会变化,这样当页面其他部分(如学员评价的实时更新)发生重渲染时,讲师信息组件不会重新渲染。
- 对于讲师信息展示组件,使用
- 高效利用缓存机制:
- 在计算学员平均评分时,使用
useMemo
。因为平均评分的计算依赖于学员评价列表,只有当学员评价列表发生变化时才重新计算平均评分,避免了每次页面渲染都重新计算。 - 在处理用户对课程评价的点赞功能时,使用
useCallback
缓存点赞处理函数。当点赞状态变化时,只有点赞按钮相关部分重新渲染,而不会导致整个课程评价区域不必要的重渲染。
- 在计算学员平均评分时,使用