最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React源码理解之reconcileChildrenArray

    正文概述 掘金(fancyluo88)   2021-02-01   530

           之前在学习React源码过程中一直对reconcileChildren的reconcileChildrenArray方法很糊,好多次对照着源码看网络的视频、博文都没能形成一个很清晰的认识。这不,最近想再沉下心把这个方法再理解下,于是在网上再次找到一篇博文阅读了下,总算是有了一个比较清晰的认识了。在此记录下自己的理解,也希望自己的解读能够帮助到同样不太清楚这个方法的小伙伴吧。

           此方法用来调和子元素为数组的情况:

    function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
        ...
        if (isArray(newChild)) {  
            //    newChild对应ClassComponent的this.render方法返回值,
            //    或者FunctionComponent执行的返回值
    
            return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
        }    ...
    }
    

          下图是reconcileChildrenArray方法的整体结构以及各块的说明:

    React源码理解之reconcileChildrenArray

         下面举个例子进行说明:
    情况1:

    // 状态改变之前
    <li key="0">0</li>
    <li key="1">1</li>
    <li key="2">2</li>
    // 状态改变之后
    <li key="0">0</li>
    <li key="1">1</li>
    <div key="2">2</div>
    <li key="3">3</li>
    

    newIndex为0、1时,前后的key、type相等节点可复用,newIndex为2时,type不等,跳出循环,此时oldFiber还有key === 2的节点未遍历,newChildren剩下key === 2、key === 3未遍历,此时去走图中编号4的逻辑进行节点的复用或者创建。

    情况2:

    // 状态改变之前
    <li key="0">0</li>
    <li key="1">1</li>
    // 状态改变之后情况1>
    
    <li key="0">00</li>
    <li key="1">11</li>
    // 状态改变之后情况2>
    
    <li key="0">0</li>
    <li key="1">1</li>
    <li key="2">2</li>
    // 状态改变之后情况3>
    
    <li key="0">0</li>
    

    这里情况1>、2>、3>分别代表第一次循环过后可能出现的三种情况,即:
    1> newChildren与oldFiber都遍历完成,reconcileChildrenArray完成;

    2> newChildren未完成,oldFiber遍历完成,此时去走图中编号3的逻辑进行节点的创建;

    3> newChildren完成,oldFiber未遍历完成,此时去走图中编号2的逻辑进行剩下oldFiber节点的删除;

           到此,整个ChildrenArray的diff逻辑大概就是这个样子。在这个函数中还有一项比较重要的顺序优化手段,这就是lastPlacedIndex的作用,我的理解是它主要用来提升状态改变后的dom操作效率,即尽可能的减少dom操作,典型的就是尽可能的减小dom的移动操作,如下图示例:

    React源码理解之reconcileChildrenArray

    过程描述:

    当然这种算法也会出现性能最差的一种情况,见下图:React源码理解之reconcileChildrenArray

            此时完成后最终的commit dom操作是旧节点key0、key1向后移动,key2保持原位置不动。但从实际情况来说此处最高效的dom操作应该是旧节点key0、key1不动,key2移动到最前面。所以在实际写代码过程中应该尽量避免将最后一个节点更新到第一个节点的位置。

            React源码中还有很多优秀的实践,比如高效的位运算、链表的应用使得更新可中断,高效的调度算法,他们的设计思路是非常值得学习和借鉴的,希望自己以后会有更多的总结输出。

    本文的写作有参考如下文章,在此对你们的分享表示感谢!

    1.https://blog.csdn.net/qiwoo_weekly/article/details/106345767;
    2.https://blog.csdn.net/susuzhe123/article/details/107890118


    起源地下载网 » React源码理解之reconcileChildrenArray

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元