繁体   English   中英

removeEventListener 不工作(函数不是匿名的,和 addEventListener 完全一样!!)

[英]removeEventListener is not working (function is not anonymous, exactly the same as addEventListener!!)

我搜索了每一篇文章,说 removeEventListener 不起作用。 其中 99% 是因为被移除的 function 与创建的 function 不匹配。 但在我的情况下,功能完全相同,但该事件根本没有被删除。

这个想法是,当组件 state 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

你能在第一个 useEffect 中添加一个“if”语句吗?

只是为了确保它不会再次添加事件侦听器。

useEffect(() => {
    console.log("useEffect1")
    console.log(isOpen[1]);
    if(!isOpen)
       document.addEventListener("scroll", scrollDetect);
  }, []);

也更新

我们可以使用“useCallback”来保持对同一个 function object 的引用,这样我们就可以确保我们使用的是同一个 function,试一试。

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是箭头 function 并且您为组件的每个渲染创建新的 function。 在 removeEventLister 中,您需要传递您在 addEventListener 中使用的相同 function。 但它永远不会发生)

对于这样的事情,你可以把它写成 function

  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)

更新你试过这样吗?

...
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", scrollDetect);
  }, []);

  useEffect(() => {
    console.log("useEffect2")
    console.log(isOpen[1]);
      document.removeEventListener("scroll", scrollDetect);
  }, [isOpen]);
...

答案是没有答案。 没有任何效果。 我将重新发布此内容,希望以更连贯的方式,看看是否有人可以提供帮助。 谢谢大家的回复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM