React的diff算法与key

相信很多人在进行列表渲染中都会习惯性的用index做为key值,如果只是单纯的数据展示,那就没问题,如果涉及到列表的动态改变,比如增加、删除、排序等,就会出现一些问题。

//this.state.list=['1','2','3']
{
	this.state.list.map((val,index)=>{
	   return(
	     <div key={index}>
	       <span>{val}</span>
	       <input type="text"/>
	      </div>
	    )
	})
}
// 改变list
 remove(){
    this.setState({list:['2','3']});
  }
  

在这里插入前端描述
点击删除按钮,动态改变列表
在这里插入图片描述

如图所示,动态改变了list的值之后,span的文字内容改变了,但是input的值没有改变

//this.state.list = [{id:1,val:'1'},{id:2,val:'2'},{id:3,val:'3'}];
{
  this.state.list.map((k, index)=>{
     return
      <li style={styles} key={k.id}>
        <p>{k.val}</p>
        <input type="text" />
      </li>
    })
}
// 改变list
 remove(){
    this.setState({list:[{id:2,val:'2'},{id:3,val:'3'}]});
  }
  

在这里插入图片描述
如上代码所示,必须给元素一个唯一的key,才可以避免这种情形发生。
下面来解释一下原因,这里是与React的优化diff算法相关,当改变list的值之后,重新渲染出来虚拟dom会和原来的dom做对比,这个对比是基于key值,原先dom的值为:[1,2,3],新的虚拟dom的值为:[1,2],经过对比,React会认为第三个key所在元素被删除,然后开始将key相同的元素进行对比,p元素的文本内容发生了改变,所以会将虚拟dom的文本内容替换,但是React会认为input组件没有发生变化,保持原状,才会造成上面那种情形出现。
所以,尽量不要用数组的index作为key值
其他注意点:

  1. key值最好保持唯一,但是这是在同级的情况下,如果是不同的父元素,则没有影响
<div>
   <div>
       <div key="1"/>
       <div key="2"/>
   </div>
   <div key="1"/>
</div>
  1. 如果是动态展示,为数据的插入设计了动态效果,那么就不要使用索引index作为key,如果是相同的key,组件不会重新生成,只会更新数据,这样会影响一些动态效果
  2. 注意,如果同一个列表项出现了相同的key,后出现的元素不会被渲染出来
{
  this.state.list.map((k, index)=>{
     return
      <li style={styles} key={k.id}>
        <p>{k.val}</p>
        <input type="text" />
      </li>
    })
}
//
change(){
    this.setState({list:[{id:2,val:'2'},{id:2,val:'3'}]});
  }

在这里插入图片描述
4. 如果实在想用索引index作为key值但是编辑器又会报错,可以这样做

{
  this.state.list.map((k, index)=>{
     return
      <li style={styles} key={parseInt(index.toString())}/>>
        <p>{k.val}</p>
        <input type="text" />
      </li>
    })
}
  1. 为了更好的性能展示,就算后台返回的数据没有特定id,前端也应该自己重新封装数组,加一个特定的id
 newArray(){
    let i=1;
    let temp = [];
    this.state.list.forEach(el=>{
      temp.push({
        ...el,
        tt:i++,
      })
     });
   console.log("temp",temp);
  }

在这里插入图片描述
6. 最后做下总结,key的增加、改变、减少,会影响React组件的生成或者销毁,不同父元素的组件的key不受影响,同一个列表下的key要保持唯一,不然会发生出局替换

参考文献:
https://www.cnblogs.com/wonyun/p/6743988.html
https://www.jianshu.com/p/fa4ca1fed4cf

猜你喜欢

转载自blog.csdn.net/kelly0721/article/details/84946712