基本概念
useEffect 的第二个参数是一个依赖数组,React 通过它来判断依赖项是否发生变化,从而决定是否重新执行 useEffect 中的副作用函数。
判断机制
React 使用 浅比较(shallow comparison) 来对比依赖数组中的值:
- 浅比较:React 会比较依赖数组中每个元素的当前值和上一次的值,使用的是
Object.is进行比较。- 如果所有依赖项的值都没有变化(
Object.is返回true),React 会跳过副作用的执行。 - 如果任何一个依赖项的值发生变化(
Object.is返回false),React 会重新执行副作用函数。
- 如果所有依赖项的值都没有变化(
示例
useEffect(() => {
console.log('Effect ran');
}, [count]); // 依赖数组包含 count
- 当
count的值发生变化时,副作用函数会重新执行。 - 如果
count的值不变,副作用函数不会执行。
注意事项
- 引用类型:对于对象或数组等引用类型,浅比较只比较引用地址,而不是内容。即使内容变化,引用地址不变,React 也会认为依赖项没有变化。
const obj = { key: 'value' };
useEffect(() => {
console.log('Effect ran');
}, [obj]); // 即使 obj 的内容变化,引用地址不变,副作用不会重新执行
- 空依赖数组:如果依赖数组为空(
[]),副作用只会在组件挂载和卸载时执行一次。
useEffect(() => {
console.log('Effect ran only once');
}, []); // 只在挂载和卸载时执行
- 无依赖数组:如果不提供依赖数组,副作用会在每次渲染后执行。
useEffect(() => {
console.log('Effect ran on every render');
}); // 每次渲染后执行
总结
React 通过浅比较依赖数组中的值来判断是否需要重新执行副作用函数。理解这一机制有助于避免不必要的副作用执行和性能问题。