面试题答案
一键面试React Hooks 中依赖数组的作用
- 控制副作用执行时机:在
useEffect
中,依赖数组用于决定副作用(如数据获取、订阅或手动 DOM 操作)的重新执行时机。当依赖数组中的某个值发生变化时,useEffect
回调函数会重新执行。如果依赖数组为空,useEffect
回调函数仅在组件挂载和卸载时执行,相当于componentDidMount
和componentDidUnmount
的结合。 - 性能优化:通过精确指定依赖,避免不必要的副作用重复执行,从而提升性能。例如,若某个副作用只依赖于一个特定的 prop,将该 prop 放入依赖数组,只有这个 prop 变化时副作用才执行,而不是每次组件重新渲染都执行。
使用 useEffect 时依赖数组设置不当引发的常见问题
- 无限循环:
- 原因:如果依赖数组缺失或者依赖了一个在
useEffect
回调函数内部会被改变的值,就可能导致useEffect
无限次执行,因为每次执行都可能再次触发重新渲染,进而再次触发useEffect
。 - 示例:
- 原因:如果依赖数组缺失或者依赖了一个在
import React, { useEffect, useState } from'react';
function InfiniteLoopComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count + 1);
}); // 缺少依赖数组,每次 useEffect 执行都会更新 count,从而导致无限循环
return <div>{count}</div>;
}
export default InfiniteLoopComponent;
- 过时数据问题:
- 原因:当依赖数组设置不完整,导致
useEffect
没有在相关数据变化时更新,从而使用了旧的数据。 - 示例:
- 原因:当依赖数组设置不完整,导致
import React, { useEffect, useState } from'react';
function StaleDataComponent() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
useEffect(() => {
setTimeout(() => {
console.log(`The count is: ${count}`);
}, 3000); // 缺少依赖数组,3 秒后打印的 count 可能是过时的
return () => {
// 清理函数
};
}, []);
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
</div>
);
}
export default StaleDataComponent;
在上述示例中,useEffect
内的 setTimeout
回调函数在 3 秒后执行,由于依赖数组为空,它不会随 count
的变化而更新,所以打印的 count
可能是过时的值。