javascript 我在removeEventListener上做错了什么?

klr1opcd  于 2023-06-28  发布在  Java
关注(0)|答案(3)|浏览(140)

我使用react useEffect钩子来创建一个下拉组件,并添加了一个事件侦听器,当用户单击下拉列表时关闭下拉列表,但也创建了一个按钮来隐藏整个下拉列表,在这种情况下,单击该按钮后组件将不存在,因此自动附加到它的ref将等于null,因此,我不得不清理删除事件侦听器时,下拉是隐藏的。
下拉菜单工作得很好,但当我点击隐藏它的按钮时,它会给予我一个错误,说
TypeError:无法读取null的属性“contains”
我猜问题出在清除函数中,当用户单击按钮完全隐藏下拉列表时,删除事件侦听器不起作用,当组件隐藏时,ref.current应该被清除,因为它等于null。

useEffect(() => {
  const onBodyClick = (event) => {
    if (ref.current.contains(event.target)) {
      return;
    }
    setopen(false);
  };
  document.body.addEventListener("click", onBodyClick);
  return () => {
    document.body.removeEventListener("click", onBodyClick);
  };
}, []);
5kgi1eie

5kgi1eie1#

:v调用useRef而不传递初始值,然后使用useEffect,这就是为什么它为null:https://reactjs.org/docs/hooks-reference.html#useref

bmvo0sr5

bmvo0sr52#

我在控制台中出现了相同的错误。经过一些挖掘,我发现了一些提到react 17中的bug的来源-https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#potential-issues
显然,这也会影响项目中安装的库。https://github.com/facebook/react/issues/20080
对我有效的解决方案是在useEffect中捕获ref:

useEffect(() => {
    const refCaptured = ref.current;
    refCaptured.addEventListener("click", onBodyClick);
    return () => {
      refCaptured.removeEventListener("click", onBodyClick);
    };
  }, []);
tsm1rwdh

tsm1rwdh3#

在下拉菜单隐藏后,ref.current的值变为null,并且您正在尝试访问ref.current上的conains方法。要解决此问题,您可以在访问ref.current的属性之前检查ref.current是否不为null

useEffect(() => {
  const onBodyClick = (event) => {
    if (ref.current && ref.current.contains(event.target)) {
      return;
    }
    setopen(false);
  };

  document.body.addEventListener("click", onBodyClick);

  return () => {
    document.body.removeEventListener("click", onBodyClick);
  };
}, []);

相关问题