如何解决如何将removeEventListener与组件状态同步?
很抱歉,代码混乱。真的让我感到纠结。
我有一个Nav
组件,我想在用户滚动时隐藏它。使用事件监听器(现在位于useEffect
中,但我不知道为什么)检测到滚动,该事件监听器调用scrollDetect()
。
scrollDetect
然后设置状态变量scrollState
,该状态变量通过样式化组件连接到CSS。
这一切都很好,除了在导航“托盘”打开时我想停止事件监听器。导航托盘的打开状态存储在isOpen[1]
中,但只是没有以正确的顺序进行更新。每当导航托盘打开时,按钮仍在滚动状态下隐藏。要查看我所指的行为,请查看deletebegin.net。尝试单击菜单按钮之一,然后滚动窗口。
我研究了各种指南,帖子和文档,但是我涉猎的圈子很多,对此有些疯狂,请帮忙。
export default function Nav() {
const [isOpen,setIsOpen] = useState(["",false]);
const [envOpen,setEnvOpen] = useState(false);
const [scrollState,setScrollState] = useState("show");
// HIDE NAVBUTTONS ON DOWN SCROLL,REVEAL ON UP SCROLL
var lastScrollTop = window.pageYOffset || window.scrollTop;
const scrollDetect = () => {
if (isOpen[1] === false) {
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st < lastScrollTop) {
setScrollState("show");
} else if (st > lastScrollTop) {
setScrollState("hide");
}
lastScrollTop = st <= 0 ? 0 : st;
}
};
useEffect(() => {
console.log(isOpen[1]);
const listener = document.addEventListener("scroll",scrollDetect);
const cleanup = () => {
document.removeEventListener("scroll",listener);
return cleanup;
};
},[isOpen[1]]);
const setOpen = ([title,state]) => {
let newState = !state;
setIsOpen([title,newState]);
};
const envelopeOpen = () => {
setEnvOpen(true);
};
const envelopeClose = () => {
setEnvOpen(false);
};
解决方法
您没有正确删除事件侦听器。请尝试以下操作:
useEffect(() => {
if (isOpen[1]) {
document.addEventListener("scroll",scrollDetect);
} else {
document.removeEventListener("scroll",scrollDetect);
}
return () => document.removeEventListener("scroll",scrollDetect);
},[isOpen]);
,
您需要两个useEffect:
-
这将一次创建一个侦听器:
useEffect(()=> { document.addEventListener(“ scroll”,scrollDetect); },[]);
-
然后,当isOpen [1]虚假时,另一个将其删除:
useEffect(()=> { 如果(!isOpen [1]){ document.removeEventListener(“ scroll”,scrollDetect); } },[isOpen]);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。