useEffect 是怎么判断依赖项变化的?

本文解释了在ReactHooksuseEffect中,当依赖项为数组或对象时,由于全等比较的特性,即使值未变,引用地址不同导致的回调函数频繁执行的问题。作者提供了详细的源码分析和解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哈喽,大家好呀,我是前端理想哥,今天我们来聊聊useEffect判断依赖项变化的方式。

好多人在刚开始使用 Hooks 时,应该都遇到过图中这样的bug,

function A() {
  const b = [{ text: 'hooks'}];

  useEffect(() => {

    console.log('b changed.');

  }, [b]);

}

大家可以看到,图中代码定义了一个值为b的数组,然后把b作为了useEffect的依赖项,本意是希望b发生改变后,会触发useEffect的回调函数,若b没有改变,则回调函数不执行。但是,当你实际运行代码时,会发现每次回调函数都会执行,这是为什么呢?

要说明白这个问题,我们可以来看看 useEffect 的源码,这张图是useEffect源码中每次用来比较依赖项是否变化的方法,

function areHookInputsEqual(nextDeps, prevDeps) {
  if (prevDeps === null) {
    return false;
  }

  for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
    if (Object.is(nextDeps[i], prevDeps[i])) {
      continue;
    }

    return false;
  }

  return true;
}

大家可以看到,是使用了 Object.is 方法来比较的,而 Object.is 的源码又是怎么去比较的呢?大家可以继续看这张图,Object.is 的源码

module.exports = function is(a, b) {

  if (a === 0 && b === 0) {
    return 1 / a === 1 / b;
  }

  if (a === b) {
    return true;
  }

  if (numberIsNaN(a) && numberIsNaN(b)) {
    return true;
  }

  return false;
};

大家可以看到,Object.is 是使用了 全等 === 来比较的,这样其实就能说明问题了。为什么上面代码中每次回调函数都会执行呢?因为useEffect的依赖项是使用了 === 全等符号来进行判断的,如果依赖项是数组或者对象,即使值没有变化,引用地址也会变化,所以每次判断的结果都不一样,就会每次都会调用回调函数了

以上,就是useEffect判断依赖项变化的方式了。

如果你觉得对自己有帮助,欢迎给理想哥一个关注,也可以私聊理想哥加入前端岗位内推群,我们会经常在群里发布各大公司急招岗位和面试求职经验,帮助大家尽快的找到工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值