React源码解析-Virtual DOM解析
前言:最近一直在研究React,看了陈屹先生所著的深入React技术栈,以及自己使用了这么长时间。对React应该说有比较深的理解了,正好前阵子也把两本关于前端设计模式的书看完了,总感觉有一种知识错综交汇,纷纷复复在脑海里交缠的感觉,真有不吐不快之感,正好也借这几篇博客融会贯通所学的知识。
目前手里研究的是React15.3.1这个版本,React版本更新很快,相关API的名字位置等都可能发生改变,不过其ReactElement的生成,渲染,移除等流程是不会改变的,在下希望略尽绵力希望能以管窥豹,笔力,能力所限之处,还望海涵。
首先,我想先说一说我对前端的看法,因为我之前一直在做.NET后端,刚开始的时候JS就是边搜边用,并没有系统了解前端,直到一年前看了JS高级程序设计,我觉得才算真正认识了JS,后来又陆陆续续看了很多前端的书,在以前的工作中因为前端的很多逻辑都可以在后台实现,前端大部分工作都是渲染数据,操作DOM等;单独JQuery完全可以搞定,不过随着对前端了解的加深,在涉及到一些很复杂的页面,用JQuery就会很明显的感受到它的缺点:首先:逻辑很乱,流水线式的DOM操作,逻辑分层不清晰,过阵子再维护需要重新过逻辑;其次:很难复用函数,通常都是一堆链式DOM调用,难以抽象出复用函数; 当然JQuery是一个非常优秀的框架,不过随着前端工程化,规模化的趋势越来越强,JQuery如果不改变,其影响力必会逐渐下降;而今,以Angular,React,Vue,Node为代表这股前端的浪潮正在扑面而来,身为一个技术人员,能经历这么一次浪潮的起伏是一次很难得的机会;
言归正传:那么回到React本身,React的创新性和优点在哪里呢?我个人认为是其用嵌套的JavaScript对象来表示DOM结构,即Virtual DOM并通过Virtual DOM的渲染过程把DOM操作放到内存里,在这个过程还可以实现DOM diff算法和DOM的生命周期管理(即,渲染DOM过程中的一些函数入口);
Virtual DOM解析
先看一下如果按照平常的思路我们操作DOM是如何操作的,基本上就是直接innerHtml赋值,appendChild(node)或者removeChild(node);这样写的话效果很直接,不过也有一些缺点显现出来:代码没有良好的结构,可扩展性,可维护性差;基本上就是一个DOM对象对应一个或多个DOM操作,很难复用函数;那么React是如何解决这些问题的呢?
就是用嵌套的JavaScript对象来表示DOM,那么这个JavaScript对象是如何表示的我们来调试一下:

我们先引入下载好的react.js和react-dom这两个文件;我们通常用的JSX语法只是一个语法糖,经过静态编译后就会编译成上图React.createElement的JS调用;这里我们直接调用该方法,看看React是如何运行的;


我们看的ReactElement其实就是一个JavaScript对象,其参数主要为:$$typeof: REACT_ELEMENT_TYPE:这是ReactElement的唯一标识类似于唯一ID,用来后续寻找这个DOM对象;
key:开发者添加的唯一标识,目前我们没有添加;props:我们可以看的我们传入的DOM属性被分析成一个对象,成为ReactElement的一个属性;ref:是可以获取渲染后的DOM的引用,这里我们先忽略;
type:就是传入的标签名,我们看的我们传入的是div;_store:是在特殊情况下做一个备份,我们先忽略它;
单有一个对象可能还不太清晰,那我们再嵌套一个对象看一下;


可以看的,父元素的props对象的一个属性children指向了刚新建的eleChildren元素;我们用对象的形式表示出来就是:
{
$$typeof: Symbol(react.element),//ReactElement的唯一标识
_owner: null,
key: undefined,//唯一标识
props: {//属性
children: {
$$typeof: Symbol(react.element),
_owner: null,
key: undefined,
props: {
children: "look~",
id: "reactChild"
},
ref: undefined,
type: "p"
},
id: "text",
onclick:"hello"//指向hello方法的指针
},
ref: undefined,//对DOM的引用
type: "div"//标签类型
}
这样的话Virtual DOM的结构就很清楚了,React正是通过这种对DOM的抽象,在抽象的DOM对象生成与最终渲染之间,完成了其组件化的设计思想;这一点我们以后将会继续介绍;
React源码解析-Virtual DOM解析的更多相关文章
- React源码解析:ReactElement
ReactElement算是React源码中比较简单的部分了,直接看源码: var ReactElement = function(type, key, ref, self, source, owne ...
- jQuery 2.0.3 源码分析Sizzle引擎解析原理
jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
- Vue源码探究-虚拟DOM的渲染
Vue源码探究-虚拟DOM的渲染 在虚拟节点的实现一篇中,除了知道了 VNode 类的实现之外,还简要地整理了一下DOM渲染的路径.在这一篇中,主要来分析一下两条路径的具体实现代码. 按照创建 Vue ...
- React躬行记(16)——React源码分析
React可大致分为三部分:Core.Reconciler和Renderer,在阅读源码之前,首先需要搭建测试环境,为了方便起见,本文直接采用了网友搭建好的环境,React版本是16.8.6,与最新版 ...
- React源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ...
- React 源码剖析系列 - 不可思议的 react diff
简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...
随机推荐
- zookeeper删除kafka元数据
问题:卸载kafka前未删除kafka topic,重新安装kafka后,生成跟之前topic名字相同的topic时报错,显示topic已存在 [root@d96 ~]# kafka-topics - ...
- 关于angularjs的$state.go()与ui-sref传参问题
上次转发过关于angularjs回退的文章,回退用到的还是js的回退功能,直接用history.back();实现功能,当时顺便提了下$state.go()有关路由跳转. 那这回就全面解析下$stat ...
- git多人合作模式的应用
接触git只有不到一年的时间,可以说比大多数人起步都晚.那会还沉浸在自己的舒适圈里面,进公司就用着perforce,一用就快7年,觉得自己会用一个SCM就行了,捧着不放,也不想去接触别的SCM. 直到 ...
- CSS控制文本在一行内显示,若有多余字符则使用省略号表示
强制文本在一行内显示,多余字符使用省略号 text-overflow: ellipsis; overflow: hidden; white-space: nowrap;
- tab切换☆☆☆☆☆
<!doctype html><html lang="en"><head> <meta charset="UTF-8" ...
- c# 读取ACCESS 数据库
using System; using System.Collections.Generic; using System.Data.OleDb; using System.IO; using Syst ...
- C# Where
判断一个字符串中是否包含字符串数组里的字符,恶意字符限制提交,一般人,包括最初的我,会这样写 public bool ValidateStr(string[] parms) { bool result ...
- react重学
知识点一:react解析中 return {__html:rawMarkup}; 这里的html前边用的是双下划线(谢谢学妹的指点)
- android studio Activity标题栏研究
第一次研究时间:2016/7/30,以下研究主要存在于当前最新版本的android studio上.eclipse请参考 一.头部标题取消 当前版本新建工程在 application中默认主题为 an ...
- [6278009]使用Visual Stuido Code 编写Markdown
使用Visual Stuido Code 编写Markdown void main() { printf("Hello world!"); } void main() { Cons ...