React的key

多个子组件的更新说明key的重要性
  • 第一种无key情况:
    更新前:
<div>
  <Test text={'one'}/>
  <Test text={'two'}/>
</div>

更新后:

<div>
  <Test text={'one'}/>
  <Test text={'two'}/>
  <Test text={'three'}/>
</div>

第一种情况,diff算法如何更新

react通过对比虚拟Dom,通过虚拟算法先更新
 <Test text={'one'}/> 
 <Test text={'two'}/>
但是因为实际内容并未改变,我们可以通过shouldComponent来阻止其更新,

然后<Test text={'three'}/>之前没有,所以添加一个实例,完成更新

  • 第二种无key情况
    更新前:
<div>
  <Test text={'one'}/>
  <Test text={'two'}/>
</div>

更新后:

<div>
  <Test text={'three'}/> // 新加的位置放在了第一位
  <Test text={'one'}/>
  <Test text={'two'}/>
 
</div>

此时如何更新;

此时react的diff算法不是简单的在首尾添加一个<Test text={'three'}/>就完成更新

因为react新旧Dom对比是按照位置来的比较的,也就是说:
<Test text={'one'}/> ----- <Test text={'three'}/> 
<Test text={'two'}/> ----- <Test text={'one'}/>
null                 ----- <Test text={'two'}/>

我们发现:由于添加的组件位置在首尾,现在不仅要新增一个组件
原来的两个组件即使一样,由于位置不同,相当于内容(props)都改变了,就得执行reconcile进行内容更新

由于react的diff算法认为props都改变了,所有必须更新
也无法通过shouldComponent来阻止更新来优化
(第一种方法位置相互对应,props没变可以通过shouldComponent来阻止更新优化)


  • 第三种有key更新
    更新前:
<div>
  <Test key={'a'} text={'one'}/>
  <Test key={'b'} text={'two'}/>
</div>

更新后:

<div>
 <Test key={'c'} text={'three'}/> // 新添加的
 <Test key={'a'} text={'one'}/>
 <Test text={'b'}/ text={'two'}>

</div>

此时diff算法更新方式

<Test key={'a'} text={'one'}/> -比较- <Test key={'a'} text={'one'}/>
<Test text={'b'}/ text={'two'}> -比较-  <Test text={'b'}/ text={'two'}>
null                            -比较- <Test key={'c'} text={'three'}/>

所以即使新添加的组件位置在首尾,但是因为有key,
diff算法会根据key去让相应的组件对比,然后确定怎么更新
所有这样以来,‘one' 'two'组件就用原来的props来启动更新,
通过shouldComponent来阻止更新,进行优化

  • 注意key的使用
一个组件中的key必须唯一,而且必须稳定,如果key变来变去,会使react作出错误判断,甚至错误的渲染


key和ref都是react保留的特殊prop,无法通过this.props.key读取

  • 为什么不要使用遍历的index作为key

##单个react组件性能优化小窍门

  • 利用react-redux的shouldComponent
diff算法可以减少dom的操作,优化性能
但是比较新旧Dom,依然是个复杂的计算过程,特别是庞大项目dom多

所以如果能够渲染前判断渲染结果不会有变化,那么阻止virtual Dom计算比较,速度更快

  • react为什么要采取这种策略

增加复用策略

在react中,每一个组件,在组件序列中唯一的标识符就是他的位置

但组件发生变化的时候,没有key就按照顺序来对比其是否发生变化,然后决定是否更新

即使A B 变成了C B A也不会复用A B,因为顺序变了,会强迫更新C B然后添加A


为什么react采取这种不聪明的做法了?
很简单,如果想要复用,就得计算出子组件序列的不同之处,他的复杂度为O(N2)
而采取傻瓜式的算法复杂度为O(N)

而为了避免浪费所以建议使用key来区分



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值