在反应项目中总会遇到这样一个的坑
这是警告数组遍历子元素要有一个唯一的关键值,但关键是到底是什么,在代码中到底起了什么作用?
中反应的关键属性,它是一个特殊的属性,它的出现不是给开发者用的(例如你为一个组件设置关键之后,也仍无法获取这个组件的键值),而是给反应自己用的。
简单来说,反应利用键来识别组件,它是一种身份标识标识,就像我们的身份证用来辨识一个人一样,每个关键对应一个组件,相同的关键反应认为是同一个组件,这样后续相同的关键对应组件都不会被创建。
在项目开发中,主要属性的使用场景最多的还是由数组动态创建的子组件的情况,需要为每个子组件添加唯一的关键属性值。那会有的人就会自然而然想到,关键和动态渲染的子元素获取的指数位置的值很接近,那不是可以直接用指数附上关键的值呢关键={指数}& # 63;
例如:
{dataList.map((项目,索引)=祝辞{ 返回& lt; div风格={mystyle}关键={指数}在{item.name} & lt;/div> }) }
在你尝试过后会发现,报错没了,渲染也没问题不是很正常嘛? !但是强烈不推荐用数组指数来作为关键。
如果数据更新仅仅是数组重新排序或在其中间位置插入新元素,那么视图元素都将重新渲染。
例如:
本来指数=2的元素向前移动后,那该元素的关键不也同样发生了改变那这样会改变的关键就没有任何的存在意义,既然是作为“身份证”一样的存在,那就不容有失。当然,在你用关键值创建子组件的时候,若数组的内容只是作为纯展示,而不涉及到数组的动态变更,其实是可以使用指数作为关键的。
我在与键值打过几次交道过后,觉得关键值就类似于数据库中的主键id一样,有且唯一。
//this.state.users内容。注意:李四和王五的id相同! ! ! 这一点。状态={ 用户:[{id: 1,名字:“张三”},{id: 2,名字:“李四”},{id: 2,名字:“王”五}), ....//省略 } 呈现() 回报( & lt; div> & lt; h4>用户列表& lt;/h4> {this.state.users。地图(u=比;& lt; div关键={u.id}在{u.id}: {u.name} & lt;/div>)} & lt;/div> ));
注意以上范例中,动态渲染的数据中,主要以数据的id来定,而李四,王五的id相同而导致关键的雷同,最后的渲染结果为张三和李四,王五并没有展示出来。主要是因为反应根据关键认为李四和王五是同一个组件(李四和王五的键值相同),导致第一个被渲染,后续的会被丢弃掉。
这样,有了关键属性后,就可以与组件建立了一种对应关系,反应根据关键来决定是销毁重新创建组件还是更新组件。
并且,关键也要保证值的稳定性,例如:
{dataList.map((项目,索引)=祝辞{ 返回& lt; div风格={mystyle}关键={math . random()}在{item.name} & lt;/div> }) }
尤其如以上范例中所示,关键的值以math . random()随机生成而定,这使得数组元素中的每项都重新销毁然后重新创建,有一定的性能开销;另外可能导致一些意想不到的问题出现。
所以,关键的值必须保证其唯一和稳定性引用>所以,在不能使用随机随机生成键时,我们可以像下面这样用一个全局的localCounter变量来添加稳定唯一的关键值。
var localCounter=1; this.data.forEach (el=祝辞{ 埃尔。id=localCounter + +; });//向数组中动态添加元素时, 函数createUser(用户){ 返回{ 用户, id: localCounter + + } } >之前
当然除了为数据元素生成的组件要添加键,且关键要稳定且唯一之外,还需要注意以下几点:
键属性是添加到自定义的子组件上,而不是子组件内部的顶层的组件上。
MyComponent//添加 … 呈现(){//错误 & lt; div关键={{item.key}}在{{item.name}} & lt;/div> } …//右 MyComponent & lt;添加关键={{item.key}}/比; >之前反应关键值的作用和使用详解