如何在Next.js/React中使onKeyDown事件生效

4
我正在使用Next.js构建网站,目前我尝试在按键时运行一个简单的函数。问题是我期望触发onKeyDown事件,但实际上并没有。我的代码如下: <main onKeyDown={e => console.log("Key pressed")}> 目前它被放置在"main"元素中,这是该组件的顶级根元素。我已经尝试将onKeyDown事件放置在许多其他元素中,但都没有成功。
我不确定是放置导致了问题,还是我缺乏如何使用此事件的理解。任何帮助将不胜感激。
我只想要在控制台中写入一些内容,以便我可以看到它是否触发。我已经尝试使用onKeyPress,并将函数分配给事件,而不是lambda表达式,但这不应该有什么区别。

1
如果您想捕获页面上所有按键事件,可能需要将事件监听器放在 windowdocument 上。除非您可以以某种方式将焦点集中在“main”上,否则我不确定它是否能够捕获该事件类型。 - tarrball
1
@tarrball 我最初的方法是这样的: globalThis.addEventListener("keydown", e => { // 做一些事情 })但我很快发现它会在网站上的所有页面触发。但还是谢谢,我会看看是否能让类似的东西起作用。 - Noobster
1
我通过将<main>的tabIndex属性设置为-1来使其工作: <main tabIndex={-1} onKeyDown={handleKeyDown}>传递一个函数handleKeyDown与此无关。 - Noobster
1个回答

6
在你的组件中,使用useEffect向文档添加(和删除)事件侦听器。
import { useEffect } from 'react'
// etc...

const Component = () => {

  useEffect(() => {
    const keyDownHandler = (e) => console.log(`You pressed ${e.code}.`);
    document.addEventListener("keydown", keyDownHandler);

    // clean up
    return () => {
      document.removeEventListener("keydown", keyDownHandler);
    };
  }, []);

  return <main>Press a key</main>;
};

您甚至可以制作自定义钩子(注意依赖项列表):

import { useEffect } from 'react'
// etc...

const useKeyDown = (handler, deps = []) => {
  useEffect(() => {
    document.addEventListener("keydown", handler);
    // clean up
    return () => {
      document.removeEventListener("keydown", handler);
    };
  }, deps);
};

const Component = () => {
  useKeyDown((e) => console.log(`You pressed ${e.code}.`), []);
  return <main>Press a key</main>;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接