现代 React Web 开发实战
宋一玮
FreeWheel 中国研发中心前端架构师
16115 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
现代 React Web 开发实战
15
15
1.0x
00:00/00:00
登录|注册

06|虚拟DOM:为什么要关心React组件的渲染机制?

你好,我是宋一玮。欢迎回到 React 组件的学习。
上节课我们从前端组件化这个概念开始,学习了 React 组件的层次结构,并用第三节课的 React 项目演练了组件拆分,引出了 React 拆分组件的基本原则,也顺带着提出 React 组件树的本质是元素树。
上节课的内容是比较多的。如果你有做过上节课的思考题,我仍然有些好奇,课上学到的内容是不是足够你完成题目。如果你顺利交卷那你真是很棒!当然,做题时遇到些难题也没关系,在这节课我会延续上节课的思路,继续讲 React 组件,重点会落在 React 组件的渲染机制上。
这节课会涉及一些 React 的底层原理,可以为你解答如下问题:
为什么我需要关心 React 组件的渲染机制?
为什么数据变了,但组件没重新渲染?
为什么数据没变,但组件也重新渲染了?
后两个问题本身都可以作为第一个问题的答案。至于后两个问题,掌握 React 组件重新渲染的时机,避免无效的重新渲染都需要学习 React 组件的渲染机制。
我们现在开始这节课的内容。

虚拟 DOM

虚拟 DOM(Virtual DOM)是前端领域近几年比较出圈的一个概念,是相对于 HTML DOM(Document Object Model,文档对象模型)更轻量的 JS 模型。在 React、Vue.js、Elm 这样的声明式前端框架中,都包含了虚拟 DOM。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

React组件渲染机制及虚拟DOM的重要性是本文的核心内容。文章深入探讨了虚拟DOM作为React开发者API与内部实现对接的桥梁,以及其在性能方面的优势。重点分析了虚拟DOM的Diffing算法和触发协调的场景,强调了只有当`props`、`state`或`context`发生变化时才会触发协调过程。此外,还介绍了Fiber协调引擎的异步协调过程和React技术的学习曲线。总的来说,本文通过深入浅出的方式解释了虚拟DOM的概念及其在React中的重要性,为读者提供了对React组件渲染机制的全面了解。文章还提出了思考题,引发读者对React内部机制的深入思考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 React Web 开发实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • Dearest
    想多了解 React Fiber, 想了解React18对实际开发的影响

    作者回复: 你好,Dearest,“React Fiber”学习心愿单+1,安排!

    2022-09-11归属地:内蒙古
    19
  • 学习前端-react
    思考题一:也是猜测。对于相同的标签元素,可能变化的就是children 和 attr。那attr来说,因为到最后都会生成一个对象去描述jsx,所以这些attrs可以做对比 简单类型可以直接做对比,引用类型可以比较是否同一个引用。类似浅拷贝。 判断数据类型目前比较常规的是通过object prototype to string call 去判断。 这时同样有一个问题如果父组件的属性发生变化 那么子组建会重新渲染吗?

    作者回复: 你好,Geek_8aba0d,很棒的回答,也很感谢你提出的问题。 你提到的“描述jsx的对象”在Fiber协调引擎中就是FiberNode。正如你说的,引用类型要比较是否同一个引用,在React底层实现中目前大量使用Object.is来判断值是否有变化。我们在接下来的第12节课单向数据流中还会涉及到这方面内容。 > 如果父组件的属性发生变化 那么子组建会重新渲染吗? 会。父组件的属性props变化,意味着父组件自己要重新渲染,父组件下面的子组件,只要不是纯组件(PureComponent),就都会重新渲染。当然,重新渲染的结果可能并没有什么需要提交的更改,从页面上看也是,子组件没有变化。

    2022-09-08归属地:内蒙古
    4
  • 海华呀
    1、相同tag,属性修改的实现 应该新旧属性都遍历一遍,遍历旧的因为要移除一些可能存在的事件监听,遍历新的是为了查看属性新增更新情况。 2、尽量不要在JSX中写大量JS语句,对事件的处理,要另外写在函数中,不要直接在JSX中写

    作者回复: 你好,海华呀,思路是ok的。有一点我稍微纠正一下,React内置的合成事件(如onClick,onChange等),不需要在对比HTML元素时移除监听,因为在React的内部实现中,合成事件是通过事件代理实现的,即React会在自己的根节点上监听所有支持的原生DOM事件,然后根据DOM事件发生时的target来触发对应的事件处理函数,这部分内容在第11节课也会提到。

    2022-10-17归属地:北京
    2
  • joel
    老师咨询一个问题: 比如一个函数组件: function A (){ return (<span>我是组件A</span>) } 是不是只要这个函数执行了,就会生成一个虚拟节点,然后通过diff 算法对比是否需要在真实的dom 结构中更新这个节点。

    作者回复: 你好,joel,抱歉这两周在赶稿回复晚了。你的理解从逻辑上是ok的。 等你学习过08组件生命周期,会发现React的内部过程会更加复杂一些: * 函数生成的还是元素,元素进入Fiber协调引擎会生成虚拟节点FiberNode; * 重新渲染产生的元素会对应到已有的虚拟节点,diffing发生在虚拟节点上; * 在提交阶段,Fiber协调引擎会一股脑地把虚拟节点上记录的变化更新到真实DOM中。

    2022-09-15归属地:北京
    2
  • 里脊
    当一个组件的状态发生变化,会触发整个虚拟dom的比对吗?

    作者回复: 你好,里脊,简单来说不会的,它只会触发子组件和后代组件的重新渲染,期间会发生相应的虚拟DOM的比对。关于这个话题,《加餐02|留言区心愿单:Fiber协调引擎》和《21|性能优化:保证优秀的用户体验》还会涉及到,欢迎你深入学习。

    2022-10-23归属地:北京
    2
    1
  • Geek_0c843c
    想多了解下react fiber

    作者回复: 你好,Geek_0c843c,“React Fiber”学习心愿单+1,我记下来了:)

    2022-09-05归属地:北京
    2
    1
  • 学习前端-react
    fiber 的理解: 首先不是普遍意义上的 parent-children 结构 而是 parent-child的结构,他是一个链表结构。 Parent-child - child - sibling,即父子关系是单向的,通过sibling完成兄弟之前的链接。 ”这棵树可以随时暂停并恢复渲染, 触发组件生命周期等副作用(Side-effect), 并将中间结果分散保存在每一个节点上, 不会 block 浏览器中的其他工作。“ 这里引用了文档中描述fiber 简要做了四件事情,但是好像都不太理解他是怎么操作的。

    作者回复: 你好,学习前端-react,是的,在这一讲对Fiber协调引擎的描述只是个简单的摘要,后面的08和加餐02,对Fiber有更详细的介绍。尤其是加餐02,我在写稿时又反复读了几遍React 18的相关源码,希望对你有所帮助。

    2022-09-17归属地:北京
  • 01
    html元素 主要是判断 props 是否相等, 简单粗暴

    作者回复: 你好,01,基本是这样的。对于HTML元素,React会比对HTML tag,也会利用Object.is() 一一比对props。

    2022-09-16归属地:北京
  • Pioneer
    想学习下react fiber

    作者回复: 你好,Pioneer,“React Fiber”学习心愿单再+1 :)

    2022-09-11归属地:内蒙古
  • 船长
    思考题 1:以我目前后端的水平我能想到的是:React 先判断属性的类型变没变,如果变了,则直接触发渲染。否则再进行值的对比

    作者回复: 你好,船长,你的答案已经很接近了。如果是原始数据类型,进行值对比,如果是对象,则进行值引用对比。在后面第12节课讲单向数据流时,我们还会讲到React如何判断state是否变化,届时会有更详细的介绍。敬请期待。

    2022-09-07归属地:内蒙古
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部