useEffect的第二个参数,是如何判断实现依赖是否发生变化的?

338 阅读2分钟

基本概念

useEffect 的第二个参数是一个依赖数组,React 通过它来判断依赖项是否发生变化,从而决定是否重新执行 useEffect 中的副作用函数。

判断机制

React 使用 浅比较(shallow comparison) 来对比依赖数组中的值:

  1. 浅比较:React 会比较依赖数组中每个元素的当前值和上一次的值,使用的是 Object.is 进行比较。
    • 如果所有依赖项的值都没有变化(Object.is 返回 true),React 会跳过副作用的执行。
    • 如果任何一个依赖项的值发生变化(Object.is 返回 false),React 会重新执行副作用函数。

示例

useEffect(() => {
  console.log('Effect ran');
}, [count]); // 依赖数组包含 count
  • count 的值发生变化时,副作用函数会重新执行。
  • 如果 count 的值不变,副作用函数不会执行。

注意事项

  1. 引用类型:对于对象或数组等引用类型,浅比较只比较引用地址,而不是内容。即使内容变化,引用地址不变,React 也会认为依赖项没有变化。
const obj = { key: 'value' };
useEffect(() => {
    console.log('Effect ran');
}, [obj]); // 即使 obj 的内容变化,引用地址不变,副作用不会重新执行
  1. 空依赖数组:如果依赖数组为空([]),副作用只会在组件挂载和卸载时执行一次。
useEffect(() => {
    console.log('Effect ran only once');
}, []); // 只在挂载和卸载时执行
  1. 无依赖数组:如果不提供依赖数组,副作用会在每次渲染后执行。
useEffect(() => {
    console.log('Effect ran on every render');
}); // 每次渲染后执行

总结

React 通过浅比较依赖数组中的值来判断是否需要重新执行副作用函数。理解这一机制有助于避免不必要的副作用执行和性能问题。