gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 15:55:56 25 4
gpt4 key购买 nike

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

{open &&
<LS.Backdrop_DIV
onClick={handleBackdropClick}
ref={backdrop_ref}
>
Backdrop
</LS.Backdrop_DIV>
}

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

Obs:这是移动 View 。

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 Uncaught TypeError: Cannot read property 'removeEventListener' of null

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

问题

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

最佳答案

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

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

而且,我找到了一种在卸载 Backdrop_DIV 之前删除监听器的方法,它有效:

  • 我添加了一个 lastOpenState_ref useRef() 来跟踪之前的渲染 open 状态,这样我就可以检测到将卸载 的渲染code>Backdrop_DIV (open === 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>
);
}

关于javascript - 如何从正在卸载的背景中删除事件监听器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57988972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com