首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从正在卸载的背景中删除事件侦听器?

如何从正在卸载的背景中删除事件侦听器?
EN

Stack Overflow用户
提问于 2019-09-18 09:04:30
回答 1查看 1.7K关注 0票数 5

我有一个Backdrop_DIV,它是基于下拉组件的open呈现的。

代码语言:javascript
运行
复制
{open &&
  <LS.Backdrop_DIV
    onClick={handleBackdropClick}
    ref={backdrop_ref}
  >
    Backdrop
  </LS.Backdrop_DIV>
}

如果用户滚动( Backdrop_DIV ) (touchmove),我希望touchmove消失。

Obs:,这是一个移动视图。

代码语言:javascript
运行
复制
const handleTouchMove = useCallback(()=>{
    setOpen(false);
  },[]);
代码语言:javascript
运行
复制
useEffect(() => {
    if (open) {
      // ATTACHING THE EVENT LISTENR
      backdrop_ref.current.addEventListener('touchmove', handleTouchMove );
    }

    // ATTEMPT TO REMOVE THE EVENT LISTENER
    return () => 
      backdrop_ref.current.removeEventListener('touchmove', handleTouchMove);

},[open,handleScroll]);

它可以工作,但如果当我试图清除useEffect返回中的事件侦听器时失败了。有办法这样做吗?

错误:

react dom.Development.js:20313未登录TypeError:无法读取空的属性“removeEventListener”

此错误非常明显,因为Backdrop_DIV在运行时不再挂载。

问题

在这种情况下,我是否需要费心删除事件侦听器?我能做什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-18 10:40:25

根据Carlene在评论中建议的问题,我想说没有必要删除事件侦听器,因为它将由垃圾收集器处理,尽管在这种情况下,一些旧浏览器可能会泄漏内存。

If a DOM Element is removed, are its listeners also removed from memory?

而且,我还找到了一种在卸载Backdrop_DIV之前删除侦听器的方法,它可以工作:

  • 我添加了一个lastOpenState_ref useRef(),跟踪以前的呈现open状态,这样我就可以检测到将卸载Backdrop_DIV (open === false)的呈现,并在呈现期间删除侦听器。

代码语言:javascript
运行
复制
import React, {useState, useEffect, useRef, useCallback} from 'react';

function MyComponent() {

  const [open,setOpen] = useState(false);
  const backdrop_ref = useRef(null);
  const lastOpenState_ref = useRef(false);

  const handleBackdropTouchMove = useCallback(() => {
    setOpen(false);
  },[]);

  // BLOCK TO REMOVE EVENT LISTENER FROM backdrop_ref
  // SINCE IT'S IMPOSSIBLE TO REMOVE FROM THE useEffect RETURN
  // BECAUSE THE backdrop_ref IS NULL WHEN IT RUNS

  if (lastOpenState_ref.current === true && open === false) {
    backdrop_ref.current.removeEventListener('touchmove', handleBackdropTouchMove);
  }
  lastOpenState_ref.current = open;

  // EFFECT TO ATTACH 'touchmove' EVENT LISTENER ON 'backdrop_ref.current'

  useEffect(() => {
    if (open) {
      backdrop_ref.current.addEventListener('touchmove', handleBackdropTouchMove);
    }
  },[open,handleBackdropTouchMove]);

  // RETURN STATEMENT

  return(
    <LS.Container_DIV>
      {open &&
        <LS.Backdrop_DIV
          onClick={handleBackdropClick}
          ref={backdrop_ref}
        >
        </LS.Backdrop_DIV>
      }
      <SomeOtherStuff/>
    </LS.Container_DIV>
  );
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57988972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档