我相信这将工作,但我认为这将更像是一个复试。还有更好的办法吗?
React 17的编辑: React 更改了处理文档级事件绑定的方式,如果在链中的某个位置调用 event.stopPropogation(),这可能导致该实现停止工作。通过将侦听器的最后一个参数更改为 true而不是 false,可以确保首先调用此函数。如果这样做并调用 event.stopPropogation(),那么以前调用的其他处理程序将不再发生,所以我建议尽可能避免调用。
event.stopPropogation()
true
false
如果您正在寻找文档级别的密钥事件处理,那么在 componentDidMount期间绑定它是最好的方法(如 Brad Colthurst 的代码示例所示) :
componentDidMount
class ActionPanel extends React.Component { constructor(props){ super(props); this.escFunction = this.escFunction.bind(this); } escFunction(event){ if (event.key === "Escape") { //Do whatever when esc is pressed } } componentDidMount(){ document.addEventListener("keydown", this.escFunction, false); } componentWillUnmount(){ document.removeEventListener("keydown", this.escFunction, false); } render(){ return ( <input/> ) } }
注意,您应该确保在卸载时删除密钥事件侦听器,以防止潜在的错误和内存泄漏。
编辑: 如果你使用钩子,你可以使用这个 useEffect结构来产生类似的效果:
useEffect
const ActionPanel = (props) => { const escFunction = useCallback((event) => { if (event.key === "Escape") { //Do whatever when esc is pressed } }, []); useEffect(() => { document.addEventListener("keydown", escFunction, false); return () => { document.removeEventListener("keydown", escFunction, false); }; }, []); return ( <input /> ) };
React 使用 合成键盘事件来包装本机浏览器事件,这个合成事件提供 命名为 key 属性,
React 使用 合成键盘事件来包装本机浏览器事件,这个合成事件提供 命名为 key 属性, 你可以这样使用:
handleOnKeyDown = (e) => { if (['Enter', 'ArrowRight', 'Tab'].includes(e.key)) { // select item e.preventDefault(); } else if (e.key === 'ArrowUp') { // go to top item e.preventDefault(); } else if (e.key === 'ArrowDown') { // go to bottom item e.preventDefault(); } else if (e.key === 'Escape') { // escape e.preventDefault(); } };
您可以使用 useState来触发某些东西,而不是 console.log。
useState
可重复使用的反应钩解决方案
import React, { useEffect } from 'react'; const useEscape = (onEscape) => { useEffect(() => { const handleEsc = (event) => { if (event.keyCode === 27) onEscape(); }; window.addEventListener('keydown', handleEsc); return () => { window.removeEventListener('keydown', handleEsc); }; }, []); } export default useEscape
用法:
const [isOpen, setIsOpen] = useState(false); useEscape(() => setIsOpen(false))
function handleEsc(event) { if (event.keyCode === 27) { close(); } } useEffect(() => { window.addEventListener("keydown", handleEsc); return () => { window.removeEventListener("keydown", handleEsc); }; }, []);
反应钩
const [add, setAdd] = useState(false); useEffect(()=>{ document.addEventListener("keydown", keydownFunction, false); return () => { document.removeEventListener("keydown", keydownFunction, false); }; }, []); const keydownFunction =(event)=>{ if (event.key === "Escape") { setAdd(false); } if (event.key === "+") { setAdd(true); }) } }