问题描述
很抱歉,代码混乱。真的让我感到纠结。
我有一个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]);