面试题答案
一键面试使用 useMemo
Hook 的常见应用场景
- 昂贵的计算:当组件中有一些计算成本较高的函数,并且这些函数的输入值在组件的多次渲染中没有变化时,可以使用
useMemo
来缓存计算结果,避免重复计算。 - 防止子组件不必要的渲染:如果父组件传递给子组件的属性是通过函数生成的,且该函数依赖于父组件的某些状态,但在父组件渲染时,这些状态并没有改变,此时使用
useMemo
可以避免子组件因为父组件渲染而重新渲染。
代码示例
示例一:缓存昂贵的计算
import React, { useState, useMemo } from 'react';
const ExpensiveCalculation = () => {
const [count, setCount] = useState(0);
const [otherValue, setOtherValue] = useState(0);
// 模拟一个昂贵的计算
const expensiveCalculation = useMemo(() => {
let result = 0;
for (let i = 0; i < 1000000; i++) {
result += i;
}
return result;
}, [count]); // 只有 count 变化时才重新计算
return (
<div>
<p>Count: {count}</p>
<p>Other Value: {otherValue}</p>
<p>Expensive Calculation Result: {expensiveCalculation}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setOtherValue(otherValue + 1)}>Increment Other Value</button>
</div>
);
};
export default ExpensiveCalculation;
在这个例子中,expensiveCalculation
函数进行了一个耗时的循环计算。useMemo
使得只有 count
状态改变时才会重新计算,当 otherValue
改变时,不会触发 expensiveCalculation
的重新计算,从而优化了性能。
示例二:防止子组件不必要的渲染
import React, { useState, useMemo } from 'react';
const ChildComponent = ({ value }) => {
console.log('ChildComponent rendered');
return <p>Child Component Value: {value}</p>;
};
const ParentComponent = () => {
const [count, setCount] = useState(0);
const [otherValue, setOtherValue] = useState(0);
const calculatedValue = useMemo(() => {
return count * 2;
}, [count]);
return (
<div>
<p>Count: {count}</p>
<p>Other Value: {otherValue}</p>
<ChildComponent value={calculatedValue} />
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setOtherValue(otherValue + 1)}>Increment Other Value</button>
</div>
);
};
export default ParentComponent;
在这个示例中,ParentComponent
传递给 ChildComponent
的 value
属性是通过 useMemo
计算得到的。只有当 count
变化时,calculatedValue
才会重新计算并传递给 ChildComponent
,otherValue
变化时,ChildComponent
不会重新渲染,因为 calculatedValue
没有改变,从而优化了 ChildComponent
的渲染性能。