react中的key

175 阅读2分钟

key的作用

  • 在某一时间节点调用react的render()方法,会创建一颗由react元素组成的树,在下一次state或props更新时,render()方法会返回一颗不同的树,react需要基于这两棵树之间的差别来判断如何有效率的更新ui一保证当前ui与最新的树保持同步
  • 当根节点为不同的元素时,react会拆卸原有的树并且建立起新的树,比如说a变成img,都会触发一个完整的重建流程;当拆卸一棵树时,对应的dom节点也会被销毁,组件实例将执行componentWillUnMount(),当建立一个新的树时,对应的dom节点会被创建以及插入到dom中,组件实例将执行componentWillMount()方法,紧接着componentDidMount()方法,所有跟之前得树锁关联的state也会被销毁
  • 当对比两个相同类型的react元素时,react会保留dom节点,仅比对及更新有改变的属性,比如className改变了,react知道只需要修改dom元素上的className属性
  • 对比同类型的组件元素,当一个组件更新时,组件实例保持不变,这样state在跨越不同的渲染时保持一致,react将更新该组件的props以跟最新的元素保持一致,并且调用该实例的componentWillReceiveProps()和componentWillUpdate()方法.
  • 对子节点进行递归,当递归dom节点的子元素时,react会同时遍历两个子元素的列表,当产生差异时,生成一个mutation,在子元素列表末尾新增元素时,更新开销比较小
  • key并不需要全局唯一,但在列表中需要保持唯一
  • 数组的下标可以作为key,这个策略在元素不就行重新排序时比较合适,但一旦有顺序修改,diff就会变得很慢
  • 当基于下标的组件进行重新排序时,组件state可能会遇到一些问题,由于组件实例是基于它们的key来决定是否更新以及复用,如果key是一个下标,那么修改顺序会修改当前的key,导致非受控组件的state可能相互篡改导致无法预期的变动
  • diff不会尝试匹配不同组件类型的子树,如果你发现你在两种不同类型的组件中切换,但输出非常相似的内容,建议把它们改成同一个类型,在实践中,我们没有遇到这类问题
  • key应该具有稳定,可观测,以及列表唯一的特质,不稳定的key会导致很多组件实例和dom节点被不必要的重新创建,这可能导致性能下降和子组件的状态丢失