【问题标题】:Difference in UseEffect and event listeners with React?使用 React 的 UseEffect 和事件监听器的区别?
【发布时间】:2020-12-31 02:07:25
【问题描述】:

所以我想了解在 React 中编写这个事件监听器有什么问题?我注意到其他人将它包装在 useEffect 钩子中并添加了一个 removeEventlistener,但我不明白这一点,因为它与我的代码做同样的事情。

这是我的代码

function App() {

 const hideMenu = () => {
   if (window.innerWidth > 768) {
   setIsOpen(false);
  }
 };

 window.addEventListener('resize', hideMenu);

}

将此代码放入 useEffect 挂钩有什么意义?为什么我不能只使用上面的代码就可以了?

这是放在 useEffect 挂钩中的相同代码

      useEffect(() => {
        const hideMenu = () => {
          if (window.innerWidth > 768) {
            setIsOpen(false);
          }
        };

        window.addEventListener('resize', hideMenu);
      }, []);

根据我的网站,这两种方法的作用完全相同,那么我如何在控制台中检查执行 useEffect 的目的与我编写它的方式?

如果屏幕大于 768px,我的功能就是隐藏移动菜单。

【问题讨论】:

  • 在没有钩子的版本中,只要您的状态发生变化,您就会添加多个事件侦听器。在带有钩子的版本中,您只需在组件挂载时添加一次事件侦听器
  • 我是否需要添加一个返回并移除事件监听器?
  • 从哪里返回?您应该只添加一次事件侦听器(就像您使用 useEffect 所做的那样),不断删除它并添加一个新侦听器并不是很有资源。
  • 下面的答案使用return,这就是我看到网上大家提到的事件监听器和react

标签: reactjs addeventlistener use-effect


【解决方案1】:

您的解决方案可能会遇到 2 个问题。

  1. 每次状态变量更改或组件重新渲染时,它都会向您的窗口添加一个新的事件侦听器。如果是空括号的使用效果,它只会在组件第一次渲染时运行,类似于“ComponentDidMount”。

  2. 如果这不是您最顶级的根组件,并且有人要离开您的屏幕,那么目前您并没有删除您的事件侦听器。这在将来可能会出现问题,或者只是在监听无用的信息。当你卸载监听器时,它保证它在未使用时已经消失,如果你要回去,它会重新添加监听器。

      useEffect(() => {
        const hideMenu = () => {
          if (window.innerWidth > 768) {
            setIsOpen(false);
          }
        };

        window.addEventListener('resize', hideMenu);

        return () => {
          window.removeEventListener('resize', hideMenu);
        }
      }, []);

【讨论】:

  • 啊,所以我 console.log() 我的 resize 函数并注意到一旦我将屏幕大小调整到 768px 以上,即使移动菜单消失了,它也会继续运行。我将如何使该功能在达到 768px 后立即停止,并且只有在我缩回到移动视图并再次打开移动菜单时才再次运行?
  • 如果经常使用resize监听器,你不需要移除它并添加它。卸载仅在不再使用组件时发生,但如果它是导航并且即使在移动设备中也始终存在,那么这很好。
  • 你会遇到其他更相关的场景。
  • 所以现在如果我在桌面视图上并将屏幕大小调整为移动设备,它会在达到 768px 之前触发函数和 console.logs 40 次。然后,一旦我将屏幕调整回桌面,它会继续 console.log 40 次,所以基本上只要屏幕调整大小,resize 函数就会运行。那不好吗?一旦屏幕大于 768 像素,我只需要一个隐藏我的移动下拉菜单的功能
  • 啊,我想通了。我删除了依赖数组,只是将 (window.innerWidth > 768 && isOpen) 添加到了 hideMenu 函数中,它只记录了一次控制台值
猜你喜欢
  • 2019-11-06
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多