我在项目中有2种不同的NavBar
组件:仅在NavBarTransparent.jsx
(主页)中使用的index.jsx
和在所有目录中都使用的NavBar.jsx
其他页面。
现在,我将函数设置为每次窗口在NavBarTransparent.jsx
组件中滚动时触发:
// components/NavBarTransparent.jsx
useEffect(() => {
window.removeEventListener('scroll', scrollFunction);
});
const scrollFunction = () => {
const nav = document.getElementById('nav');
const overlay = document.getElementById('nav-overlay');
const travel = document.documentElement.scrollTop;
const travelRem = travel / 16;
const navHeight = 7 - (travelRem / 6);
if (navHeight <= 4) {
nav.style.lineHeight = `${4}rem`;
overlay.style.opacity = 1;
} else if (navHeight >= 7) {
nav.style.lineHeight = `${7}rem`;
overlay.style.opacity = 0;
} else {
nav.style.lineHeight = `${navHeight}rem`;
overlay.style.opacity = (7 - navHeight) / 3;
}
};
另一个导航栏组件(NavBar.jsx
)没有此事件侦听器。但是,当我从/about
(客户端路由)访问/
时,事件监听器仍然会触发。为什么当其他页面甚至不使用该组件时,监听器也会受到打击?
回购位于https://github.com/amitschandillia/proost/tree/master/web
答案 0 :(得分:0)
修复了以下问题:
useLayoutEffect(() => {
if(transparent) { window.addEventListener('scroll', scrollFunction); }
// returned function will be called on component unmount
return () => {
window.removeEventListener('scroll', scrollFunction);
}
}, []);
看起来像在组件安装之前添加的窗口事件侦听器必须在组件卸载之前显式删除。我通过useEffect
钩子添加了侦听器,但没有卸载它,因此存在持久性触发器的问题。现在,我使用了return()
的{{1}}代码段(相当于useEffect
的Hooks)来删除侦听器,并且工作正常。
此外,我使用componentWillUnmount
而不是useLayoutEffect
,因为如果要操作DOM并在浏览器绘制之前进行操作(例如此处的情况),则useLayoutEffect`是更可取的