React:div 上的按键监听器

Eig*_*ght 1 javascript typescript reactjs

我目前在组件上创建按键侦听器(或任何侦听器)时遇到问题。

本质上,我希望每当我按下“ESC”时都会触发我的监听器,但我发现自己被阻止了。

我的功能组件非常简单,如下所示:


const Component = () => {
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.isComposing || e.keyCode === 27) {
        console.log('do something');
      }
    };

    window.addEventListener('keydown', handler, false);
    return () => window.removeEventListener('keydown', handler, false);
  }, []);

  return <div />;
};
Run Code Online (Sandbox Code Playgroud)

当我的组件被安装时,window监听器被正确添加。不幸的是,组件卸载后,事件侦听器并未被删除。

所以我尝试将事件侦听器专门添加到我正在安装的 div 中:


const Component = () => {
  const ref = useRef(null);
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.isComposing || e.keyCode === 27) {
        console.log('do something');
      }
    };

    const divRef = ref.current as any;

    divRef.addEventListener('keydown', handler, false);
    return () => divRef.removeEventListener('keydown', handler, false);
  }, []);

  return <div ref={ref} />;
};
Run Code Online (Sandbox Code Playgroud)

但这根本不起作用,并且处理程序永远不会被调用。

小智 5

将处理程序保留在 useEffect 之外,这样应该可以工作。我们只需在挂载时附加该函数并在卸载时删除该函数。


const Component = () => {
 const handler = (e: KeyboardEvent) => {
      if (e.isComposing || e.keyCode === 27) {
        console.log('do something');
      }
    };

  useEffect(() => {
       window.addEventListener('keydown', handler, false);
    return () => window.removeEventListener('keydown', handler, false);
  }, []);

  return <div />;
};

Run Code Online (Sandbox Code Playgroud)