详解React组件卸载怎么中止递归方法

 更新时间:2024年01月29日 08:40:43   作者:TA_WORDL  
最近在处理项目代码的时候,出现了一个bug,组件中的方法在组件卸载后仍然在执行,代码片段发给我看,但是变量的用意我也不懂,只看到有方法调用自身方法,这不就是递归嘛,所以本文详细给大家介绍了React组件卸载怎么中止递归方法,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

问题的出现——组件卸载怎么中止递归方法

朋友在处理弹幕相关业务的时候,出现了一个bug:组件中的方法在组件卸载后仍然在执行。代码片段发给我看,但是变量的用意我也不懂,只看到有方法调用自身方法,这不就是递归嘛(最后发现是定时器没有清除的问题)?。

递归的中止这还不简单,在方法中添加一个中止条件不就好了。

const Children = () => {
  const [isStop, setStop] = useState(false)
  
  // 递归
  const recursion = async (num: number) => {
    if (isStop) return
    console.log(num)
    await sleep(1000)
    recursion(num + 1)
  }
  
  useEffect(() => {
    recursion(1)
    return () => {
      setStop(() => true)
    }
  }, [])
  
  return (
    <div>Children</div>
  )
}

const HomePage: React.FC = () => {
  const [flag, setFlag] = useState(false)
  return (
    <div>
      <Button onClick={() => setFlag(!flag)}>点击</Button>
      {
        flag && <Children></Children>
      }
    </div>
  );
};

结果与预期好像不太一样,突然仔细想一下,当组件卸载时,所有与该组件相关的状态(通过useState定义的状态)都会被清除,这怎么可能会有效呢!

简单闭包处理

既然状态在组件卸载的时候被清理了,那么在递归内部增加状态来控制递归不就行了。闭包就很适合现在的场景。

  const controller = () => {
    // 递归的状态(开始/结束)
    let state = false
    // 递归方法
    const recursion = async (num: number) => {
      // 结束条件
      if (state === false) return
      console.log(num)
      await sleep(1000)
      recursion(num + 1)
    }
    return {
      // 开启递归
      start: (num: number) => {
        state = true
        recursion(num)
      },
      // 结束递归
      close: () => state = false
    }
  }

我们在挂载结束后创建一个单一实例用来控制递归方法,并在卸载的时候将递归的状态改为false即可。如果需要在组件的其他位置使用,还是使用useRef对实例进行包裹比较好。

  useEffect(() => {
    let c = controller()
    c.start(1)
    return () => {
      c.close()
    }
  }, [])

Hook useRef处理

const Children = () => {
  const isUnmounted = useRef(false);
  
  // 递归
  const recursion = async (num: number) => {
    if (isUnmounted.current) return
    console.log(num)
    await sleep(1000)
    recursion(num + 1)
  }
  
  useEffect(() => {
    recursion(1)
    return () => {
      isUnmounted.current = true
    }
  }, [])
  
  return (
    <div>Children</div>
  )
}

const HomePage: React.FC = () => {
  const [flag, setFlag] = useState(false)
  return (
    <div>
      <Button onClick={() => setFlag(!flag)}>点击</Button>
      {
        flag && <Children></Children>
      }
    </div>
  );
};

来自CHAT-GPT

这是因为useRef创建的引用对象是在组件的闭包中存在的,而不是作为组件的状态存在。所以即使组件卸载,引用对象仍然可以被访问和修改。

个人理解,useRef创建的引用对象在递归方法中被引用,类似闭包的原理,所以在组件卸载的时候没有被清理。(如果理解错误,欢迎指正,轻点喷?)

用途

我觉得在页面请求完数据之后,需要对数据进行复杂递归处理的时候,又把页面关闭,这种情况可能需要。

到此这篇关于详解React组件卸载怎么中止递归方法的文章就介绍到这了,更多相关React中止递归方法内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • 解决React报错Cannot assign to 'current' because it is a read-only property

    解决React报错Cannot assign to 'current'

    这篇文章主要为大家介绍了React报错Cannot assign to 'current' because it is a read-only property的解决方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • react router 4.0以上的路由应用详解

    react router 4.0以上的路由应用详解

    本篇文章主要介绍了react router 4.0以上的路由应用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 谈谈React中的Render Props模式

    谈谈React中的Render Props模式

    这篇文章主要介绍了谈谈React中的Render Props模式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • 适用于React?Native?旋转木马应用程序介绍

    适用于React?Native?旋转木马应用程序介绍

    这篇文章主要介绍了适用于React?Native?旋转木马应用程序介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • react路由基础解读(Router、Link和Route)

    react路由基础解读(Router、Link和Route)

    这篇文章主要介绍了react路由基础解读(Router、Link和Route),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • React+CSS?实现绘制竖状柱状图

    React+CSS?实现绘制竖状柱状图

    这篇文章主要介绍了React+CSS?实现绘制竖状柱状图,文章围绕主题展开详细的内容介绍。具有一定的参考价值,需要的朋友可以参考一下
    2022-09-09
  • React中用@符号编写文件路径实现方法介绍

    React中用@符号编写文件路径实现方法介绍

    在Vue中,我们导入文件时,文件路径中可以使用@符号指代src目录,极大的简化了我们对路径的书写。但是react中,要想实现这种方式书写文件路径,需要写配置文件来实现
    2022-09-09
  • React使用context进行跨级组件数据传递

    React使用context进行跨级组件数据传递

    这篇文章给大家介绍了React使用context进行跨级组件数据传递的方法步骤,文中通过代码示例给大家介绍的非常详细,对大家学习React context组件数据传递有一定的帮助,感兴趣的小伙伴跟着小编一起来学习吧
    2024-01-01
  • 一文详解React类组件中的refs属性

    一文详解React类组件中的refs属性

    react中的ref类似于vue中的ref,都是可以操作dom的,这篇文章我们通过一个demo来学习这个属性,文中有详细的代码示例供大家参考,具有一定的参考价值,需要的朋友可以参考下
    2023-08-08
  • 优雅的在React项目中使用Redux的方法

    优雅的在React项目中使用Redux的方法

    这篇文章主要介绍了优雅的在React项目中使用Redux的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11

最新评论


http://www.vxiaotou.com