首页 > 解决方案 > removeEventListener 不工作(函数不是匿名的,和 addEventListener 完全一样!!)

问题描述

我搜索了每一篇文章,说 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", scrollDetect);
    }
  }, [isOpen]);

更新:在这里回购 https://github.com/erasebegin/portfolio-2020

使用 create-react-app 创建npm/yarn start

标签: javascriptreactjsuse-effectremoveeventlistener

解决方案


你能在第一个 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 希望这次能成功


推荐阅读