英文:
removeEventListener not working in UseEffect
问题
我的问题可能看起来很愚蠢,但我已经搜索了解决方案好几天,尝试了多次更改,但都没有成功。问题如下:
我有一个使用脚本执行视差效果的React组件。我使用一个事件监听器,所以当我在组件上滚动时,它会触发脚本。然而,我希望在继续滚动时删除这个事件监听器。removeEventListener
不起作用,所以当我切换页面时出现错误(因为脚本找不到 Div)。
这是我的组件(我删除了前端代码,只保留了逻辑部分):
const GridTextParallax = () => {
// 当组件出现在页面上时触发脚本
const { trigger, inView } = useInView({
threshold: [0, 0.8],
});
const parallax = (scrolling) => {
if (scrolling > 0) {
// 所有完美运行的视差逻辑
}
}
useEffect(() => {
if (inView) {
document.addEventListener('scroll', () => {
var scrolling = // 执行计算组件内滚动速率的逻辑;
parallax(scrolling)
});
return () => { window.removeEventListener('scroll', parallax); };
} else {
console.log("在视口外")
window.removeEventListener('scroll', parallax);
}
}, [inView]);
return (
<section id="layer" ref={trigger} >
所有前端代码...
</section>
)
}
export default GridTextParallax
我错过了什么?
非常感谢
英文:
My question may seems stupid but I searched the solution for days, tried multiple changes nothing works. Here it is:
I have a React component that uses a script to perform a parallax effect. I use an eventlistener so when I scroll on the component it fires the script. However, I would like to remove this eventlistener when I continue the scroll. The removeEventListener doesn't work so when I change page I got an error (because the script doesn't find the Div).
Here is my component (I removed the front code which works fine to just keep the logic):
const GridTextParallax = () => {
//trigger the script when component appear on the page
const { trigger, inView } = useInView({
threshold: [0, 0.8],
});
const parallax = (scrolling) => {
if (scrolling > 0) {
//All the parallax logic that works perfect
}
}
useEffect(() => {
if (inView) {
document.addEventListener('scroll', () => {
var scrolling = // perform the logic to calculate the scrolling rate within the component;
parallax(scrolling)
});
return () => { window.removeEventListener('scroll', parallax); };
} else {
console.log("outside viewport")
window.removeEventListener('scroll', parallax);
}
}, [inView]);
return (
<section id="layer" ref={trigger} >
All the front end...
</section>
)
}
export default GridTextParallax
What did I miss?
Thanks a lot
答案1
得分: 1
你需要将相同的回调实例同时传递给addEventListener
和removeEventListener
,以便移除监听器。在你的情况下,你将一个匿名箭头函数传递给addEventListener
,而将paralax
函数传递给removeEventListener
。
解决方法是将回调写入变量中,并在addEventListener
和removeEventListener
中都使用它:
const cb = () => {
var scrolling = // 在组件内部执行计算滚动速率的逻辑;
parallax(scrolling)
}
addEventListener("scroll", cb)
return () => {
removeEventListener("scroll", cb)
}
英文:
You need to pass the same instance of callback to both addEventListener
and removeEventListener
for the listener to be removed. In your case you're passing an anonymous arrow function to addEventListener
and paralax
function to removeEventListener
.
The solution is to write the callback into a variable and use it in both addEventListener
and removeEventListener
:
const cb = () => {
var scrolling = // perform the logic to calculate the scrolling rate within the component;
parallax(scrolling)
}
addEventListener("scroll", cb)
return () => {
removeEventListener("scroll", cb)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论