为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

倚天杖 2021-10-21 10:53:46
我有一个Backdrop_DIV基于open下拉组件的a 呈现的。{open &&  <LS.Backdrop_DIV    onClick={handleBackdropClick}    ref={backdrop_ref}  >    Backdrop  </LS.Backdrop_DIV>}Backdrop_DIV如果用户滚动 ( touchmove),我希望它消失。Obs:这是一个移动视图。const handleTouchMove = useCallback(()=>{    setOpen(false);  },[]);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 未捕获的类型错误:无法读取 null 的属性“removeEventListener”这个错误很明显,因为Backdrop_DIV它在运行时不再挂载。题在这种情况下,我需要费心删除事件侦听器吗?我能做什么?
查看完整描述

1 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

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

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

  • 我添加了lastOpenState_ref useRef()对先前渲染open状态的跟踪,以便我可以检测将卸载Backdrop_DIVopen === false)的渲染,并在该渲染期间移除侦听器。

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>

  );

}


查看完整回答
反对 回复 2021-10-21
  • 1 回答
  • 0 关注
  • 162 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信