Ste*_*ous 5 javascript keyboard-events reactjs
我正在尝试向 React 中的图标添加事件侦听器,但它不起作用。我的代码:
const handleKey = (event) => {
console.log(event);
}
<MdOutlinePause onKeyDown={handleKey} />
Run Code Online (Sandbox Code Playgroud)
我在同一个按钮上还有一个 onClick 处理程序,功能正常,所以我真的很困惑为什么 onKeyDown 不触发。感谢任何人可以提供的帮助!
在某个元素上使用 onKeyDown 将需要焦点才能按预期工作。
我们可以通过添加tabindexMdOutlinePause属性使您的组件可聚焦。这将允许您通过点击选项卡或单击图标来获得图标焦点。该元素看起来像这样:
<MdOutlinePause tabIndex={0} onKeyDown={handleKey} />
Run Code Online (Sandbox Code Playgroud)
如果您想检测按键事件而不需要聚焦元素,则需要附加一个事件侦听器。我们可以使用useEffect来做到这一点,这样就可以在 onMount 上执行此操作,并且我们将事件侦听器附加到 ,window以便无论哪个元素具有焦点它都可以工作:
<MdOutlinePause tabIndex={0} onKeyDown={handleKey} />
Run Code Online (Sandbox Code Playgroud)
这允许您检测键盘事件,这很棒,但有一个问题:每当页面安装时,事件监听器就会再次添加,但永远不会被删除。因此,您可能会遇到每次按键时多次调用函数的问题。
我们可以通过删除useEffect 返回中的事件侦听器来解决此问题。这就是我们如何指定一个函数来让其自行useEffect 清理。这确保我们useEffect一次不会添加多个“keydown”事件监听器:
/// Don't copy and paste this - see below
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
});
}, []);
/// Don't copy and paste this - see below
Run Code Online (Sandbox Code Playgroud)
这是codesandbox 上的完整示例
如果您不需要访问handleKeyPress函数中的状态,这非常有用。
当用户执行某个操作时,需要对状态变量执行某些操作是一个常见的用例,如果我们需要访问更新后的状态,那么我们会遇到一个问题:我们附加handleKeyPress到事件侦听器 onMount 并且该函数永远不会更新,因此它将始终使用状态的初始版本。这个codesandbox说明了这个问题。
我们可以通过添加handleKeyPress到 useEffect 的依赖项数组来解决这个问题,但这会导致我们的事件侦听器被删除并在每个渲染上重新添加,因为handleKeyPress将在每个渲染上更新。更好的解决方案是将回调模式与我们一起使用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]);
Run Code Online (Sandbox Code Playgroud)
现在一切都正确更新了!这是codesandbox 上的完整示例。
还有一种解决方案可以让您以最简单的方式访问状态。缺点是您有权访问的唯一状态变量(具有更新的值)将是您正在更新的状态变量,因此此解决方案是视情况而定的。要访问其他状态变量,您必须使用上面的解决方案。
通过将函数传递给 useState,我们可以访问先前的状态作为函数的第一个参数。这允许采用更简单的方法,如下所示和此codesandbox中所示。
const [text, setText] = useState("");
const handleKeyPress = event => {
setText(previousText => `${previousText}${event.key}`);
};
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5454 次 |
| 最近记录: |