Next+TypeScript+React自定义键盘映射触发构造函数报错如何解决
问题根因
- 报错是因为你错误将从
react包导入的**合成事件类型KeyboardEvent**当作浏览器原生构造函数使用。React提供的KeyboardEvent仅用于TypeScript类型标注,不能实例化,创建原生键盘事件需要调用全局window.KeyboardEvent构造函数。 - 原有方案还缺了原事件的默认行为阻止,会导致原按键逻辑和模拟按键逻辑同时触发,出现预期外的效果。
完整解决方案
处理逻辑说明
- 所有匹配到的自定义按键规则,都先调用
e.preventDefault()阻止原事件生效 - 字符类按键(A/D)直接修改输入框值即可,不需要额外模拟事件
- 功能类按键(ArrowDown)模拟原生
ArrowRight事件分发 - 类型标注适配TypeScript规范
代码实现
import { useRef, KeyboardEvent } from 'react' // 注意这里的KeyboardEvent是从react导入的合成事件类型,仅用于类型标注 const drunkenKeyboard = (e: KeyboardEvent<HTMLInputElement>) => { const input = e.currentTarget // 先阻止原事件默认行为 e.preventDefault() switch(e.code) { case 'KeyA': // 追加字符C到当前光标位置,兼容光标不在末尾的情况 const start = input.selectionStart || 0 const end = input.selectionEnd || 0 input.value = input.value.slice(0, start) + 'C' + input.value.slice(end) // 调整光标位置到插入字符之后 input.selectionStart = input.selectionEnd = start + 1 break case 'KeyD': const startD = input.selectionStart || 0 const endD = input.selectionEnd || 0 input.value = input.value.slice(0, startD) + 'X' + input.value.slice(endD) input.selectionStart = input.selectionEnd = startD + 1 break case 'ArrowDown': // 用window下的原生KeyboardEvent构造实例 const arrowRightEvent = new window.KeyboardEvent('keydown', { key: 'ArrowRight', code: 'ArrowRight', bubbles: true, cancelable: true }) input.dispatchEvent(arrowRightEvent) break default: // 其他按键不拦截,恢复默认行为 e.defaultPrevented = false break } } // 组件内使用 export default function TestInput() { const inputRef = useRef<HTMLInputElement>(null) return <input onKeyDown={drunkenKeyboard} ref={inputRef} /> }
额外适配注意点
- 如果使用受控组件(value绑定state),不要直接修改input.value,改为调用state的setter方法更新值即可
- 若需要适配输入法等特殊输入场景,可以额外监听
beforeinput事件做规则校验
内容的提问来源于stack exchange,提问作者Mocha
相关产品推荐
相关产品推荐

