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 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...
随机推荐
- Python random模块(获取随机数)常用方法和使用例子
random.randomrandom.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0 random.uniformrandom.uniform(a, b),用 ...
- 用备份控制文件做不完全恢复下的完全恢复(数据文件备份<旧>--新建表空间--控制文件备份<次新>--日志归档文件<新>)
为什么会使用备份的控制文件? 实际工作中主要有两种情况:第一种:当前控制文件全部损坏,而数据文件备份,控制文件备份及当前日志处于不同SCN版本,它们之间又增加过表空间(数据文件).第二种:当前控制文件 ...
- Apache的htaccess文件出现500错误的原因
Apache 我平时很少用到,今天测试环境下碰到个问题,老是500错误莫名其妙 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FI ...
- [HMLY]11.iOS函数式编程的实现&&响应式编程概念
简介 本篇主要回顾一下--iOS函数式编程 && 响应式编程概念 ,如何一步步实现函数式编程的过程,对阅读Masonry && SnapKit源码有一定的帮助. 作为一 ...
- 第一百三十三节,JavaScript,封装库--弹出登录框
JavaScript,封装库--弹出登录框 封装库,增加了两个方法 yuan_su_ju_zhong()方法,将获取到的区块元素居中到页面,chuang_kou_shi_jian()方法,浏览器窗口事 ...
- sublime & atom 插件
1. autofilename(sublime) autocomplete-paths (atom): 自动路径 2. autoprefixer: 自动添加前缀 : https://github.c ...
- JavaEE XML DOM创建之DOM4J
DOM4J创建xml文档 @author ixenos 1 写出内容到xml文档 XMLWriter writer = new XMLWriter(OutputStream, OutputForamt ...
- JavaEE XML SAX解析
SAX解析XML @author ixenos SAX解析工具 SAX解析工具- Sun公司提供的.内置在jdk中.org.xml.sax.* 核心的API: SAXParser类: 用于读取和解析 ...
- 安卓---app自动更新
主要参考:http://blog.csdn.net/jdsjlzx/article/details/46356013/ 效果如下: 大致思路:[原文] 首先,我们要有一个可以被手机访问的后台. 这里有 ...
- 【转】gcc/g++ 如何支持c11 / c++11标准编译
如果用命令 g++ -g -Wall main.cpp 编译以下代码 : 1 2 3 4 5 6 7 8 9 10 11 12 /* file : main.cpp */ #include ...