react中 input自动失去焦点解决办法和原因

问题

小组小伙伴开发过程中,遇到遍历 input 渲染在页面,再通过input框操作修改数据的过程中,出现input失去焦点问题。
去帮忙排查问题的时候,起初分析是 onChange 方法的问题,因为项目里业务逻辑比较复杂,方法的转换有很多层级,从上到下一步步排查都没能找到原因。偶然间看到外层遍历的key值用的时间戳,再想到react的机制,便知道原因了

代码示例如下:

import React, { useState } from 'react';
import { Input } from 'antd';

const index = () => {

    const [userArr, setUserArr] = useState<any[]>([
        { val:'你好你好1' },
        { val:'你好你好2' },
        { val:'你好你好3' },
    ]);

    const fns = (index:number, e:any)=>{
        const userArrR = JSON.parse(JSON.stringify(userArr));
        userArrR[index].val = e.target.value;
        setUserArr(userArrR);
    }

    return (
        <div>
            {
                userArr.map((item, index)=>{
                    return (
                        <div key={ index + new Date().getTime() }>
                            <Input value={ item.val } onChange={ fns.bind(this, index) } />
                        </div>
                    )
                })
            }
        </div>
    );
}
export default index

可以看到key值使用了时间戳

key={ index + new Date().getTime() }

这个时候的key是会动态变化的,因为每次数据状态发生变化都会触发render 重写渲染,即视图重写渲染

解决办法:

将map遍历时绑定的key的值改为不是动态变化的值(例如index 每一项的索引值,或给每一项设置一个固定的key或id)

原因:

在react中,每一次输入都会触发onChange事件都会重新调用render(),所以每一个item都需要一个唯一的确定的key值,这个key的作用就是避免diff算法重新生成一个全新的dom,所以每当绑定的key变化时diff算法就会生成一个全新的dom,进而导致每次输入都会导致input会失去焦点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。