手动移除事件监听器反应钩子

Posted

技术标签:

【中文标题】手动移除事件监听器反应钩子【英文标题】:Remove event listener manually react hooks 【发布时间】:2019-12-08 00:00:46 【问题描述】:

我有一个滚动事件侦听器,我想根据页面 URL 删除它,如何在钩子组件中使用它来处理它?

 useEffect(() => 
    function handleScrollEvent() 
      if (window.scrollY > 100) 
        setHeaderIsVisible(true);
       else 
        setHeaderIsVisible(false);
      
    
    if (props.location.pathname === "/") 

      window.addEventListener("scroll", handleScrollEvent, true);
     else 
      window.removeEventListener("scroll", handleScrollEvent, true);
    
  , [props.location.pathname]);

我应该在哪里定义 handleScrollEvent 以将其从侦听器中移除?

【问题讨论】:

您在正确的位置定义了handleScrollEvent。你在做什么有什么问题? @Vencovsky 它不起作用。我认为可能是它正在重新定义函数并将一个新函数传递给removeListener。我不确定! It doesn't work定义你的意思 监听器仍然存在并且在移除后可以工作。 Listener still exists and works after removing. 你确定要删除它吗?可能发生的情况是效果没有运行,因为props.location.pathname 没有改变 【参考方案1】:

你需要做的是每次添加它,你也删除它。

props.location.pathname发生变化时,会移除事件监听器。

useEffect(() => 
    if (props.location.pathname === "/")   
      function handleScrollEvent() 
        if (window.scrollY > 100) 
          setHeaderIsVisible(true);
         else 
          setHeaderIsVisible(false);
        
      

      window.addEventListener("scroll", handleScrollEvent, true);  
      // every time you add it, you also remove it when props.location.pathname changes
      return () => 
           window.removeEventListener("scroll", handleScrollEvent, true);
      
    
  , [props.location.pathname]);

【讨论】:

不,我不想在组件卸载时删除监听器。我根据当前位置将其删除。 @HadiRanjbar 试试这个。当props.location.pathname === "/" 时,您将只有事件监听器 @HadiRanjbar:如果组件已卸载,为什么要保留此事件侦听器?这似乎会导致内存泄漏。 @Vencovsky 它出奇地有效,我不知道为什么! 那么你的第一条评论就更令人困惑了。当props.location.pathname 发生变化时,useEffect 将在每次更新之前执行清理。并且还在卸载。文档中有详细解释:reactjs.org/docs/hooks-effect.html#effects-with-cleanup

以上是关于手动移除事件监听器反应钩子的主要内容,如果未能解决你的问题,请参考以下文章

移除一个元素是不是也会移除它的事件监听器? [复制]

如何通过js实现添加事件监听和移除事件监听

移除另一个脚本设置的点击事件监听器

移除类添加的事件监听器

vue 监听函数发生事件

怎样理解js中的事件监听