正常情况下,比较两个树形结构的差异的算法的时间复杂度为O(n^3),这个效率显然无法直接接收的,react通过总结DOM的实际使用场景提出了两个在绝大多数实践场景下都成立的假设,基于这两个假设,react实现了在O(N)的复杂度内完成两颗虚拟dom树的比较,这两个假设是

1. 如果两个元素的类型不同,那么将生成两颗不同的树
2. 为列表中的元素设置key属性,用key标识对应的元素在多次render中是否发生变化

在下面介绍的不同情况下,React具体是如何比较两颗树的异同的。React比较两棵树是从树的根节点开始比较的,根节点的类型不同,react执行的操作也不同

1.根节点类型不同
在这种情况下,react会认为新的树和旧的树完全不一样,所以他不会再去比较子节点的异同,而是把整颗树拆掉重建(包括虚拟dom和真实dom)。虚拟dom的节点类型分为2类,一类是Dom元素类型,例如div,p。另一类是react组件类型。

2当根节点是相同的Dom元素类型时.
在这种情况下,React会保留根节点,而比较根节点的属性,然后只更新那些变化了的属性。
例如:

<div className="foo" title=""react></div>
<div className="bar" title=""react></div>

在这里,react只更新虚拟dom树和真实dom树种对应节点的这一属性(注:在vue中,类名不同,会被直接认同为类型不同。)

3.根节点是相同类型的组件类型时
在这种情况下,对应的组件的实例将不会被销毁,只是会执行更新操作,同步变化的属性到虚拟dom上去。注意对于组件类型的节点,react是无法直接知道如何更新真实dom树的,需要在组件更新并且render执行完成后,根据render返回的虚拟dom结构决定如何更新真实的dom树
比较完跟节点之后,react会以同样的原则继续递归比较子节点,直到比较完两棵树的所有节点,计算得到差异,更新到dom树上。

如何使用key属性

我们在之前讲过,相比vue的两头遍历节点的方式,react从左到右的单边遍历,是明显吃亏的,例如如果只是在子节点的开始位置新增一个节点,那么react就需要遍历所有节点,然后才能发现差异 。
为了弥补这种低效的方式,raect提供了一个key属性,尤其对于列表元素,react希望所有列表元素都能有一个独一的key属性,以便于在进行列表更新时,react能跟根据key快速检索出哪些数据是变化了的,这依赖于key在更新前后保持不变。但是真的注意一点的是,尽量不要使用元素在列表中的索引值作为key,一旦元素顺序改变,大量的key就会失效

2.react的diff算法(2020.12.07)相关推荐

  1. 2.vue的diff算法(2020.12.07)

    在之前的生命周期中有提到过虚拟dom的相关概念,这里来简单介绍一个vue的diff算法的原理 1.virtual dom 无论是vue还是react,在更新渲染的过程中,都是先根据真实dom生成一个虚 ...

  2. React中diff算法的理解

    React中diff算法的理解 diff算法用来计算出Virtual DOM中改变的部分,然后针对该部分进行DOM操作,而不用重新渲染整个页面,渲染整个DOM结构的过程中开销是很大的,需要浏览器对DO ...

  3. vue和react的diff算法对比

    vue和react的diff算法,都是忽略跨级比较,只做同级比较.vue diff时调动patch函数,参数是vnode和oldVnode,分别代表新旧节点. vue比对节点,当节点元素类型相同,但是 ...

  4. vue与react的diff算法

    我们都知道的一件事,就是vue和react框架,核心算法都是diff算法,啥叫diff算法可能有一部分人都是没有深究的,今天梳理一下vue和react的diff算法,也说一下有啥区别 什么叫虚拟dom ...

  5. React:DOM Diff算法

    React中最神奇的部分莫过于虚拟DOM,以及其高效的Diff算法.这让我们可以无需担心性能问题而"毫无顾忌"的随时"刷新"整个页面,由虚拟DOM来确保只对界面 ...

  6. 2020.12.07.记录

    def plot_learning_curve(algo, X_train, X_test, y_train, y_test):"""绘制学习曲线:只需要传入算法(或实例 ...

  7. 2020/12/07工作小结

    1.Q: 关于模型没问题,损失正常下降,降到一定就收敛了,但是精度达不到预期且损失过大. A: 1. 查数据分布,很可能是样本不均衡带来的问题. 2. 有可能模型欠拟合,可以考虑换更大的模型. Q: ...

  8. diff算法_详解 React 16 的 Diff 策略

    这是我 Deep In React 系列的第二篇文章,如果还没有读过的强烈建议你先读前一篇:详谈 React Fiber 架构(1). 前言 我相信在看这篇文章的读者一般都已经了解过 React 16 ...

  9. React中的Diff算法——Christopher Chedeau(原文翻译)

    React's diff algorithm是了解React中的Diff算法必读的文章之一,以下内容是我在阅读过程中边看边翻译的,非科班渣翻请谅解.强烈建议阅读英文原文. 原文地址: React's ...

最新文章

  1. Atom介绍和安装步骤
  2. 【60岁老人年审】老来网app养老保险年审的好伙伴【本地年审】【异地年审】【不参加年审无法领取养老保险金】...
  3. 如何直接强制客户端刷新.js文件
  4. Java的权限修饰符,访问范围
  5. mysql存储过程局部变量使用_MySQL存储过程使用输出变量
  6. 正则表达式学习笔记007--字符组简记法1
  7. Java SE作业:判断一个字符串是否是视频文件
  8. html登录界面QQ微信图标,discuz修改QQ登录图标和微信登录图标的方法
  9. 最新win11 JDK环境变量的配置
  10. JDK和JRE安装与下载
  11. tampermonkey(油猴)跨域发送请求
  12. qsnctf 哥哥打篮球 wp
  13. android照片裁剪
  14. 高二退学,她如今是年收50亿“独角兽”掌门人
  15. mh采样算法推导_科学网—MCMC中的Metropolis Hastings抽样法 - 张金龙的博文
  16. 微众银行张开翔: FISCO BCOS - 开放的区块链实践之道 | 11月25日【区块链技术与实践】论坛...
  17. 为什么服务器未响应ins,9修复Instagram无法正常工作,加载或崩溃的最佳方法
  18. 2、Redis的常用命令
  19. Python的len()函数
  20. 如何做出一份赏心悦目的PPT

热门文章

  1. 编译mysql 5.7 源码安装常见问题
  2. bootstrap ace admin 整合java HTML5
  3. .net 下载文件几种方式
  4. Android动画-帧动画
  5. ADO.NET Entity Framework如何:使用实体数据模型向导(实体框架)
  6. 让你人际关系更上一层楼的26条原则
  7. Java中的泛型使用
  8. 从理解Future模式到仿写JUC的Future模式
  9. freeswitch 用户配置详解_FreeSwitch安装配置记录-阿里云开发者社区
  10. 高中必备学习软件_10个适合高中生学习的网站amp;软件,完全免费,9科全覆盖!...