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",[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”来保留对同一函数对象的引用,这样我们可以确保使用的是同一函数,给它一个机会。

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

对于这种事情,您可以将其编写为函数

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

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

答案是没有答案。没事。我打算以更连贯的方式重新发布此内容,看看是否有人可以提供帮助。谢谢大家的答复。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...