解决输入框按下回车键时finishEditText()重复调用问题
问题描述
我有如下输入框,希望通过按下回车键或失焦来结束编辑:
<input ref={titleEditBox} type="text" onBlur={blurEditBox} onKeyDown={keyDownFinishEdit}></input> const blurEditBox = () =>{ finishEditbox(); } const keyDownFinishEdit = (e) =>{ if (e.keyCode == 13){ finishEditText(); } e.stopPropagation(); }
但按下回车键时,会先触发keyDownFinishEdit,再触发onBlur,导致结束编辑的方法被调用两次。我的想法是在keyDownFinishEdit中让输入框失焦,请问这是否可行?或者有什么更好的解决方案?
解决方案
- 你的思路是可行的,但要调整逻辑避免重复执行:按下回车时,直接调用输入框的
blur()方法触发失焦逻辑,不要单独调用结束编辑的函数。因为失焦后会自动触发blurEditBox执行结束逻辑,这样就能保证只执行一次。修改后的代码:
const keyDownFinishEdit = (e) =>{ if (e.keyCode === 13){ titleEditBox.current?.blur(); // 触发输入框失焦 e.preventDefault(); // 阻止回车键默认行为(如表单提交) } e.stopPropagation(); }
- 更稳妥的方案是给结束逻辑加一个状态标志位,防止短时间内重复执行:
- 定义一个状态变量标记是否处于编辑状态
- 执行结束逻辑前先判断状态,只有在编辑状态时才执行,执行后切换状态
- 输入框获得焦点时重置状态
代码示例:
import { useState, useRef } from 'react'; // ... const titleEditBox = useRef(null); const [isEditing, setIsEditing] = useState(true); const blurEditBox = () =>{ finishEdit(); } const keyDownFinishEdit = (e) =>{ if (e.keyCode === 13){ finishEdit(); e.preventDefault(); } e.stopPropagation(); } const finishEdit = () => { if (!isEditing) return; // 这里写你的结束编辑逻辑 setIsEditing(false); } const focusEditBox = () => { setIsEditing(true); } // ...
然后给输入框加上onFocus={focusEditBox}:
<input ref={titleEditBox} type="text" onBlur={blurEditBox} onKeyDown={keyDownFinishEdit} onFocus={focusEditBox}></input>
- 还可以统一结束逻辑,减少重复代码:把回车和失焦触发的逻辑合并到同一个函数中,再结合标志位就能彻底避免重复调用。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

