Dogtiti / Blogs

:sparkling_heart:一起记笔记呀~
8 stars 6 forks source link

为什么不推荐用数组index作为key值遍历?会产生什么样的效果? #56

Open yixiaosi1314 opened 3 years ago

yixiaosi1314 commented 3 years ago

key的作用

在react或者Vue中,都是使用了虚拟DOM和diff算法更新视图。key就是虚拟DOM对象的唯一标识。

更新过程

当状态中的数据发生变化时,react会根据新数据生成新的虚拟DOM,随后React进行新虚拟DOM与旧虚拟DOM的diff比较

旧虚拟DOM中找到了与新虚拟DOM相同的key:
(1).若虚拟DOM中内容没变, 直接使用之前的真实DOM
(2).若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
旧虚拟DOM中未找到与新虚拟DOM相同的key:
        根据数据创建新的真实DOM,随后渲染到到页面

举例说明

为了方便就简写一下代码

arr:[
     {id:1,name:'小张',age:18},
         {id:2,name:'小李',age:19},
]
//此时如果我们要对数组进行添加操作,比如添加一个:
{id:3,name:'小王',age:'20'}

当我们要在数组开头添加元素,如果我们使用index作为key的话

旧虚拟DOM                            
 key:0    {id:1,name:'小张',age:18},
 key:1    {id:2,name:'小李',age:19},

新的虚拟DOM
 key:0    {id:3,name:'小王',age:20}, 
 key:1    {id:1,name:'小张',age:18},
 key:2    {id:2,name:'小李',age:19},

此时上次通过虚拟DOM创建的真实DOM中的key1,key2的内容都发生了改变,就都不能使用,需要重新创建所有的真实DOM,对实际的页面效果不会产生影响,但是就严重影响了效率问题。

当我们使用id做key时
旧虚拟DOM                            
 key:1    {id:1,name:'小张',age:18},
 key:2    {id:2,name:'小李',age:19},

 新的虚拟DOM
 key:3    {id:3,name:'小王',age:20}, 
 key:1    {id:1,name:'小张',age:18},
 key:2    {id:2,name:'小李',age:19},

此时我们发现,在原先旧虚拟DOM创建的真实DOM中key1和key2的内容都没有发生改变,所以在新的虚拟DOM生成新的真实DOM时,只需要添加一个key3就可以了,原来的key1,key2都可以直接拿来用,这就大大提高了效率。

在对数组进行添加删除操作时,使用index作为key的话,会大大影响效率,但是如果只对数组从后面进行添加删除操作的话不会有什么影响。

旧虚拟DOM                            
 key:0    {id:1,name:'小张',age:18},
 key:1    {id:2,name:'小李',age:19},

 新的虚拟DOM 
 key:0    {id:1,name:'小张',age:18},
 key:1    {id:2,name:'小李',age:19},
 key:2    {id:3,name:'小王',age:20},
 //此时真实DOM中原来的key0,key1都是可以复用的,只需要重新生成key2就可以了