面试题答案
一键面试使用React.memo优化UserInfo组件性能
- 常规函数组件写法:
import React from'react';
const UserInfo = ({ name, age }) => {
return (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
};
export default UserInfo;
- 使用React.memo优化:
import React from'react';
const UserInfo = React.memo(({ name, age }) => {
return (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
});
export default UserInfo;
通过将UserInfo
组件包裹在React.memo
中,React会在组件接收到新的props时,对新旧props进行浅比较。如果比较结果为props没有变化,则不会重新渲染该组件,从而优化性能。
React.memo浅比较时对属性对象的判断逻辑
- 基本类型属性:
- 对于基本类型(如字符串、数字、布尔值等),React.memo会直接比较它们的值。如果值相同,则认为props没有变化。例如,当
name
属性从'John'
变为'Jane'
,这是不同的值,组件会重新渲染;但如果name
还是'John'
,则不会重新渲染。
- 对于基本类型(如字符串、数字、布尔值等),React.memo会直接比较它们的值。如果值相同,则认为props没有变化。例如,当
- 对象类型属性:
- React.memo的浅比较只会比较对象的引用地址。如果两个对象的引用地址相同,React.memo会认为props没有变化,即使对象内部的属性值发生了改变。例如:
import React, { useState } from'react';
const UserInfo = React.memo(({ user }) => {
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
</div>
);
});
const App = () => {
const [user, setUser] = useState({ name: 'John', age: 30 });
const handleClick = () => {
// 创建一个新的对象,引用地址改变
setUser({ name: 'John', age: 31 });
};
return (
<div>
<UserInfo user={user} />
<button onClick={handleClick}>Update User</button>
</div>
);
};
export default App;
在上述例子中,每次点击按钮,user
对象的引用地址改变了(即使name
值相同,age
值改变),UserInfo
组件会重新渲染。如果想避免这种情况,可以使用immer等库来更新对象,保持引用地址不变,这样React.memo的浅比较就能生效,避免不必要的渲染。