即使卸载组件,也无法停止window.onScroll的触发

时间:2019-08-28 10:09:15

标签: javascript reactjs next.js

我在项目中有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

1 个答案:

答案 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`是更可取的