gpt4 book ai didi

javascript - React 中的 onKeyDown/onKeyUp 监听器

转载 作者:行者123 更新时间:2023-12-05 03:26:10 24 4
gpt4 key购买 nike

我正在尝试将事件监听器添加到 React 中的图标,但它不起作用。我的代码:

const handleKey = (event) => {
console.log(event);
}

<MdOutlinePause onKeyDown={handleKey} />

我在同一个按钮上还有一个 onClick 处理程序,它运行良好,所以我真的很困惑为什么 onKeyDown 没有触发。感谢任何人可以提供的任何帮助!

最佳答案

在特定元素上使用 onKeyDown 需要焦点才能按预期工作。

我们可以通过添加 tabindex 使您的 MdOutlinePause 组件可聚焦属性。这将允许您通过点击选项卡或单击它来为图标提供焦点。该元素看起来像这样:

<MdOutlinePause tabIndex={0} onKeyDown={handleKey} />

如果您希望无需聚焦元素即可检测键事件,您需要附加一个事件监听器。我们可以用 useEffect 来做到这一点所以这发生在 Mount 上,我们会将事件监听器附加到 window,这样无论哪个元素具有焦点,它都能正常工作:

  /// Don't copy and paste this - see below
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
});
}, []);
/// Don't copy and paste this - see below

这允许您检测键盘事件,这很好,但有一个问题:每当页面加载时 eventListener 会再次添加,但永远不会被删除。因此,您可能会遇到函数在每次按键时被多次调用的问题。

我们可以通过删除 return from useEffect 中的事件监听器来解决这个问题.这就是我们如何指定一个函数让 useEffect 清理 自身。这确保了我们的 useEffect 永远不会一次添加多个“keydown”事件监听器:

  useEffect(() => {
window.addEventListener("keydown", handleKeyPress);

return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);

这是完整的 example on codesandbox

如果您不需要在 handleKeyPress 函数中访问状态,这会非常有用。


这是一个常见的用例,当用户执行某个操作时需要对状态变量做一些事情,如果我们需要访问更新后的状态,那么我们就会遇到一个问题:我们附加了 handleKeyPress到事件监听器 onMount 并且该函数永远不会更新,因此它将始终使用状态的初始版本。 This codesandbox说明了这个问题。

我们可以通过将 handleKeyPress 添加到 useEffect 的依赖项数组来解决这个问题,但这会导致我们的事件监听器被删除并在每次渲染时重新添加,因为 handleKeyPress 将在每个渲染器上更新。更好的解决方案是使用 callback pattern 与我们的 handleKeyPress 以便它只在实际需要时更新(当它依赖的状态被更新时)。我们还想将 handleKeyPress 添加到我们的 useEffect 依赖项数组中,以便在 handleKeyPress 函数更改时创建一个新的事件监听器:

  const handleKeyPress = useCallback((event) => {
// do stuff with stateVariable and event
}, [stateVariable]);

useEffect(() => {
window.addEventListener("keydown", handleKeyPress);

return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [handleKeyPress]);

现在一切都适本地更新了! Here's a full example这个在 codesandbox 上。


还有一种解决方案可以让您以最简单的方式访问状态。缺点是您唯一可以访问的状态变量(具有更新的值)将是您正在更新的状态变量,因此此解决方案是视情况而定的。要访问其他状态变量,您必须使用上述解决方案。

通过 passing a function对于 useState,我们可以访问前一个状态作为函数的第一个参数。这允许采用更简单的方法,如下所示和 this codesandbox 中所示。 .

  const [text, setText] = useState("");

const handleKeyPress = event => {
setText(previousText => `${previousText}${event.key}`);
};

useEffect(() => {
window.addEventListener("keydown", handleKeyPress);

return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);

关于javascript - React 中的 onKeyDown/onKeyUp 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71822354/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com