问题描述
我拖了每条帖子,说removeEventListener不起作用。其中99%是因为要删除的功能与创建的功能不匹配。但就我而言,功能完全是相同的,但事件并没有在应有的情况下完全删除。
这个想法是,当组件状态为isOpen[1]===true
时,事件侦听器应该发出臭虫。但事实并非如此。我似乎没有做任何事情都能使removeEventListener正常工作!我已经在组件中的所有位置进行了记录,并且一切都以正确的顺序进行。 useEffect
在正确的时间接收到正确的信号以激活removeEventListener
,但是侦听器仍然存在!
请帮助。发疯。
更新:在所有建议之后,这是当前代码。变化不大,但是我已经尝试了所有的解决方案(谢谢)
const [isOpen,setIsOpen] = useState(["",false]);
const [panelHeight,setPanelHeight] = useState({ skills: 0,contact: 0 });
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;
function scrollDetect() {
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st < lastScrollTop) {
setScrollState("show");
} else if (st > lastScrollTop) {
setScrollState("hide");
}
lastScrollTop = st <= 0 ? 0 : st;
}
const setOpen = ([title,state]) => {
let newState = !state;
setIsOpen([title,newState]);
};
const setHeight = (title,height) => {
setPanelHeight((prevState) => ({ ...prevState,[title]: height }));
};
const envelopeOpen = () => {
setEnvOpen(true);
};
const envelopeClose = () => {
setEnvOpen(false);
};
useEffect(() => {
if (!isOpen[1]) {
document.addEventListener("scroll",scrollDetect);
}
},[]);
useEffect(() => {
if (isOpen[1]) {
document.removeEventListener("scroll",[isOpen]);
更新:在此处回购 https://github.com/erasebegin/portfolio-2020
使用create-react-app创建,因此仅npm/yarn start
解决方法
您可以在第一次useEffect时添加“ if”语句。
只是为了确保它没有再次添加事件监听器。
useEffect(() => {
console.log("useEffect1")
console.log(isOpen[1]);
if(!isOpen)
document.addEventListener("scroll",scrollDetect);
},[]);
也要更新
我们可以使用“ useCallback”来保留对同一函数对象的引用,这样我们可以确保使用的是同一函数,给它一个机会。
const scrollDetect = useCallback(() => {
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st < lastScrollTop) {
setScrollState("show");
} else if (st > lastScrollTop) {
setScrollState("hide");
}
lastScrollTop = st <= 0 ? 0 : st;
},[]);
annnnnd希望这次能够奏效
, scrollDetect
是箭头函数,您可以为组件的每个渲染创建新函数。
在removeEventLister中,您需要传递与addEventListener中使用的相同的函数。但这永远不会发生)
对于这种事情,您可以将其编写为函数
function scrollDetect() {
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st < lastScrollTop) {
setScrollState("show");
} else if (st > lastScrollTop) {
setScrollState("hide");
}
lastScrollTop = st <= 0 ? 0 : st;
};
或者您可以在useEffect中初始化此功能)
更新 你尝试过那样吗?
...
function scrollDetect(){
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st < lastScrollTop) {
setScrollState("show");
} else if (st > lastScrollTop) {
setScrollState("hide");
}
lastScrollTop = st <= 0 ? 0 : st;
};
const setOpen = ([title,state]) => {
let newState = !state;
setIsOpen([title,newState]);
};
const setHeight = (title,height) => {
setPanelHeight((prevState) => ({ ...prevState,[title]: height }));
};
const envelopeOpen = () => {
setEnvOpen(true);
};
const envelopeClose = () => {
setEnvOpen(false);
};
useEffect(() => {
console.log("useEffect1")
console.log(isOpen[1]);
document.addEventListener("scroll",[]);
useEffect(() => {
console.log("useEffect2")
console.log(isOpen[1]);
document.removeEventListener("scroll",[isOpen]);
...
,
答案是没有答案。没事。我打算以更连贯的方式重新发布此内容,看看是否有人可以提供帮助。谢谢大家的答复。