React中如何在contentEditable div上捕获InputEvent类型的onInput事件
问题根源
React 内置类型定义中,所有onInput事件的回调参数默认被标注为FormEvent合成事件类型,该类型未声明inputType属性,因此直接将参数声明为原生InputEvent类型会触发TS类型校验报错。虽然运行时事件对象实际携带inputType字段,但静态类型检查无法识别。
可行方案
不要直接将回调参数类型标注为原生InputEvent,React 中onInput拿到的永远是封装后的合成事件,而非原生DOM事件,直接修改参数类型会导致后续访问合成事件自带方法(如preventDefault、persist)时触发新的类型错误,推荐两种写法:
- 方案1:通过
nativeEvent访问原生InputEvent(最规范,无类型兼容问题)
const inputChanged = (e: React.FormEvent<HTMLDivElement>) => { // 断言原生事件为InputEvent类型 const inputEvent = e.nativeEvent as InputEvent; if (inputEvent.inputType === 'historyUndo' || inputEvent.inputType === 'historyRedo') { // 编写撤销、重做的自定义处理逻辑 } } return <div contentEditable={true} onInput={inputChanged}> 可编辑区域内容 </div>
- 方案2:扩展合成事件类型(适合React 16.8+版本,该版本后合成事件已透传
inputType字段)
// 给FormEvent扩展inputType字段类型 type ContentEditableInputEvent = React.FormEvent<HTMLDivElement> & { inputType: InputEvent['inputType'] } const inputChanged = (e: ContentEditableInputEvent) => { if (e.inputType === 'historyUndo' || e.inputType === 'historyRedo') { // 编写撤销、重做的自定义处理逻辑 } }
补充说明:如果需要拦截浏览器默认的撤销/重做行为,仅靠
onInput事件无法阻止默认逻辑,需要额外在onKeyDown事件中判断对应快捷键(Ctrl/Cmd + Z 对应撤销、Ctrl/Cmd + Y / Ctrl/Cmd + Shift + Z 对应重做),调用e.preventDefault()拦截默认行为后再执行自定义逻辑。
内容的提问来源于stack exchange,提问作者Alvin Stefanus
相关产品推荐
相关产品推荐

