ReactJs中input触发onChange事件后自动失焦问题如何解决?
React输入框触发变更后自动失焦解决方案
问题根因&对应解决办法
- 列表渲染使用
index作为元素key属性
这是最常见的导致列表内输入框失焦的原因:当你修改数组内某一项的内容后,下标为index的元素对应内容变化,React 会根据key判断是否需要重建DOM节点,用index当key会触发对应位置DOM的销毁重建,输入框自然失焦。
解决办法:初始化header数组时给每一项添加唯一固定标识(比如uuid、自增id、时间戳),渲染列表时用这个唯一标识作为key,禁止用数组下标当key。
- 列表渲染使用
- 状态更新不符合不可变数据原则
你当前的代码仅对state做了第一层浅拷贝,嵌套的headers数组仍然是原引用,且直接修改了数组内的元素,不符合React不可变更新的规范,容易触发异常重渲染。
修改更新逻辑为逐层拷贝所有需要修改的嵌套结构,参考代码如下:
- 状态更新不符合不可变数据原则
headerKeyValueChanger = ({ target }, key, index) => { this.setState(prevState => { // 逐层拷贝嵌套结构,不修改原状态的引用 const newServiceInputSection = { ...prevState.fieldsValueData.serviceInputSection, headers: prevState.fieldsValueData.serviceInputSection.headers.map((item, i) => { if (i !== index) return item const [oldHeaderKey, oldHeaderValue] = item.split(':') return key === 'key' ? `${target.value}:${oldHeaderValue}` : `${oldHeaderKey}:${target.value}` }) } return { fieldsValueData: { ...prevState.fieldsValueData, serviceInputSection: newServiceInputSection } } }) }
- 传递给子组件的事件处理函数每次渲染重新生成
如果在render方法中直接用匿名函数绑定事件,比如onChange={(e) => headerKeyValueChanger(e, 'key', index)},每次父组件渲染都会生成新的函数引用,导致子组件不必要的重渲染,触发输入框重绘失焦。
解决办法:
- 给输入框对应的子组件用
React.PureComponent(类组件)或者React.memo(函数组件)包裹,做props浅比较跳过不必要的重渲染 - 提前绑定事件处理函数的参数,不要在render中生成新的匿名函数
- 传递给子组件的事件处理函数每次渲染重新生成
- Context传递的value每次渲染生成新对象
你通过Context传递header数据时,如果每次给Provider的value属性传递新生成的对象,所有消费该Context的组件都会触发重渲染,也可能导致输入框失焦。
解决办法:将Context需要传递的value存在父组件的state中,仅当value内容变化时才更新引用,不要每次render都重新生成value对象。
- Context传递的value每次渲染生成新对象
内容的提问来源于stack exchange,提问作者Amirhossein Lashgari
相关产品推荐
相关产品推荐

