我正在尝试为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
组件具有焦点功能。这将允许您通过按Tab或单击来使图标获得焦点。该元素可能如下所示:
<MdOutlinePause tabIndex={0} onKeyDown={handleKey} />
window
上,以便它可以在任何有焦点的元素上工作。 /// Don't copy and paste this - see below
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
});
}, []);
/// Don't copy and paste this - see below
useEffect
在自身清理后运行的方式。这确保了我们的useEffect
不会同时添加超过一个“keydown”事件侦听器: useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);
这里有一个完整的 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]);
还有一种解决方案可以让您以最简单的方式访问状态。缺点是您只能访问到正在更新的状态变量(带有更新后的值),因此这种解决方案是情境性的。要访问其他状态变量,您必须使用上面介绍的解决方案。
通过将函数传递给useState,我们可以将先前的状态作为函数的第一个参数进行访问。这样可以实现更简单的方法,如下所示,并在此codesandbox中显示。
const [text, setText] = useState("");
const handleKeyPress = event => {
setText(previousText => `${previousText}${event.key}`);
};
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);