美文网首页
React Reconciliation

React Reconciliation

作者: shuxiaotai | 来源:发表于2020-02-18 19:41 被阅读0次

    React Reconciliation

    一.什么是Reconciliation

    1. 每次render的时候,React都会产生一棵由React元素组成的树,这个树形结构就是所谓的虚拟DOM,下次render的时候又会产生新的一颗树,对比这两棵树的不同的过程,就是调和,即Reconciliation

    二.对比过程,分为以下几种情况

    1. 根节点类型不同的情况
    • 如果根节点就不同,如下的div变成了span,那么对比的开销太大了,所以React选择了重建,会将原有的树卸载,再将新的树装载
    <div>
      <Counter />
    </div>
    
    <span>
      <Counter />
    </span>
    
    2.根节点类型相同的情况
    • 如果是根节点相同的情况下,只会更改有变化的部分

    • 当节点类型是HTML元素类型时(如span,p,div等)

    如下,只会更改color变化的值和div里变化的值

    <div style={{color: 'red', fontWeight: 'bold'}}>hello world</div>
    
    <div style={{color: 'green', fontWeight: 'bold'}}>good bye</div>
    
    • 当节点类型是React组件类型时

      如下,React并不知道如何去更新DOM,因为这些逻辑还在React组件当中,所以只能去更新props的值,引发这个组件的更新过程,实现对子元素的递归

      <Todo text="old">
      
      <Todo text="new">
      
    3.多个同级元素的情况
    • 有时候我们会遇到增加同级元素的情况,这里以HTML元素为例,React组件也是一样
    • 如果是在最下方插入的情况,那么事情没那么糟糕,因为React会去对比每个元素,first对比fisrtsecond对比second,然后发现多了一个third,那么就在原有的基础上加上这个元素
    • 但是如果是在最上方插入的情况,React使用的O(n)复杂度的算法会逐个对比,即first对比thirdsecond对比first,然后发现多了一个second,这样的话,本来只是新增一个元素的情况,会变成全部元素都要修改
    //最下方插入
    
    <ul>
      <li>first</li>
      <li>second</li>
    </ul>
    
    <ul>
      <li>first</li>
      <li>second</li>
      <li>third</li>
    </ul>
    
    //最上方插入
    
    <ul>
      <li>first</li>
      <li>second</li>
    </ul>
    
    <ul>
      <li>third</li>
      <li>first</li>
      <li>second</li>
    </ul>
    
    • 有没有解决上面最上方插入所带来的问题的方法呢,答案是使用唯一的Key
    • 当使用了唯一的Key以后,React会知道,firstsecond是原来的那个元素,现在新增的只是third元素,当然这里有很重要的一点,这个Key必须是稳定不变的,试想一下,如果原先first是1,second是2,后面third是1,first是2,second是3,这样的话,从上到下一一对比,每个元素又要重新渲染,就失去了Key的意义,导致不必要的元素重新创建和子组件中的状态丢失【1】
    //最上方插入
    
    <ul>
      <li key={1}>first</li>
      <li key={2}>second</li>
    </ul>
    
    <ul>
      <li key={0}>third</li>
      <li key={1}>first</li>
      <li key={2}>second</li>
    </ul>
    

    三.代码优化思考

    1.以前早就听说过不要用数组下标作为Key,但是现在才对Key值需要唯一且稳定有了深刻理解,具体理解见上面的【1】,数组下标作为Key也不是一棒子打死,当这些元素不需要重新排序的时候,可以采用,当这个元素需要重新排序的时候,就不要用数组下标了

    2.也不要用Math.random()作为Key

    3..针对React对根节点类型不同的情况的处理,在写代码的时候就要避免改变根节点的情况

    相关文章

      网友评论

          本文标题:React Reconciliation

          本文链接:https://www.haomeiwen.com/subject/cmdnfhtx.html