'window.removeEventListener('keydown')' 在 react hooks 函数中不起作用



我在无状态组件中使用react钩子。以下是源代码:

const MyComp = ({focused}) => {
...
const keyPressListener = (e: KeyboardEvent) => {
    console.log('key press:', e);
  };
useEffect(() => {
    if (focused) {
      console.log('add event listener');
      window.addEventListener('keydown', keyPressListener);
    } else {
      console.log('remove event listener');
      window.removeEventListener('keydown', keyPressListener);
    }
  }, [focused]);
...
}

它侦听酒店focused。当它为真时,它会添加键下侦听器,当它变为假时,它会将其删除。我可以看到有关add/remove event listener的控制台日志,但删除后仍会调用keyPressListener函数。我看到很多人都有同样的问题,因为他们没有绑定函数。但我认为在这种情况下箭头功能不需要它。

每当focused道具的值发生变化时,MyComp都会重新渲染。每次重新渲染时,都会创建一个新的keyPressListener函数。此新函数由 useEffect 挂钩在 keypress 事件中添加或删除。

因此,从 keypress 事件中删除的不是以前添加keyPressListener而是以前甚至没有添加的新创建的函数。最终结果是原始keyPressListener保留添加到keypress事件中。

解决方案 1

你移动keyPressListener可以移出MyComp。这是在keypress事件中添加和删除时将引用的相同函数。

解决方案 2

您可以记住keyPressListener函数,以便在keypress事件中添加和删除相同的函数。由于您使用的是钩子,因此您可以继续使用useMemouseCallback

const MyComp = ({ focused }) => {
  const keyPressListener = ({ code }) => {
    console.log('key press:', code);
  };
  const memoizedListener = useMemo(() => keyPressListener, []);
  // or use 
  // const memoizedListener = useCallback(keyPressListener, []);
  console.log('rendered again');
  useEffect(() => {
    if (focused) {
      console.log('add event listener');
      window.addEventListener('keydown', memoizedListener);
    } else {
      console.log('remove event listener');
      window.removeEventListener('keydown', memoizedListener);
    }
  }, [focused, memoizedListener]);
  return <h1>Test component</h1>;
};

希望这可以帮助您理解上述代码的工作原理。

在使用中附加 EventListener 效果钩子通常需要"清理"。像这样重写你的useEffect钩子:

useEffect(() => {
  if (focused) {
    console.log('add event listener');
    window.addEventListener('keydown', keyPressListener);
  }
  return () => {
    console.log('remove event listener');
    window.removeEventListener('keydown', keyPressListener);
  };
}, [focused]);

您还可以使用useRef钩子来包含要在清理时删除的事件侦听器回调。

最新更新