我试图在React中的图标中添加一个事件侦听器,但它不起作用.我的代码:
const handleKey = (event) => {
console.log(event);
}
<MdOutlinePause onKeyDown={handleKey} />
我在同一个按钮上也有一个onClick处理程序,可以正常工作,所以我真的很困惑onKeyDown为什么不能启动.感谢任何人能提供的帮助!
我试图在React中的图标中添加一个事件侦听器,但它不起作用.我的代码:
const handleKey = (event) => {
console.log(event);
}
<MdOutlinePause onKeyDown={handleKey} />
我在同一个按钮上也有一个onClick处理程序,可以正常工作,所以我真的很困惑onKeyDown为什么不能启动.感谢任何人能提供的帮助!
如果要将onKeyDown添加到某个元素,则需要专注才能工作.
我们可以通过添加tabindex属性使MdOutlinePause
组件可以聚焦.这将允许你通过点击标签或点击图标来获得焦点.元素看起来像这样:
<MdOutlinePause tabIndex={0} onKeyDown={handleKey} />
如果要检测关键事件without,必须聚焦元素you will need to attach an event listener.我们可以用useEffect来实现这一点,所以这发生在mount上,我们将把事件监听器连接到window
,这样不管哪个元素有焦点,它都可以工作:
/// Don't copy and paste this - see below
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
});
}, []);
/// Don't copy and paste this - see below
这允许您检测键盘事件,这很好,但有一个问题:the eventListener gets added again whenever the page mounts,但永远不会被删除.因此,您可能会遇到函数在每次按键时被多次调用的问题.
我们可以通过删除return from useEffect中的事件侦听器来解决这个问题.这就是我们如何指定一个函数,让useEffect
clean up在其自身之后.这确保了我们的useEffect
一次不会添加多个"按键"事件侦听器:
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);
如果您不需要访问handleKeyPress
函数中的状态,这将非常有用.
当用户执行某个操作时,通常需要对状态变量执行一些操作,如果我们需要访问更新的状态,那么我们会遇到一个问题:我们将handleKeyPress
附加到事件侦听器onMount,函数永远不会更新,因此它将始终使用状态的初始版本.This codesandbox说明了这个问题.
我们可以通过为useEffect将handleKeyPress
添加到dependencies数组来解决这个问题,但这会导致我们的事件侦听器被删除,并在每个渲染中重新添加,因为handleKeyPress
将在每个渲染中更新.更好的解决方案是使用handleKeyPress
更新use the 100 pattern,这样它只在实际需要时更新(当它所依赖的状态更新时).我们还希望将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]);
现在一切都适当地更新了!在codesandbox上有Here's a full example个.
还有一个解决方案可以让您以最简单的方式访问状态.缺点是,您可以访问的唯一状态变量(具有更新的值)将是您正在更新的状态变量,因此此解决方案是情境性的.要访问其他状态变量,必须使用上面的解决方案.
通过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);
};
}, []);