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源码解析-Virtual DOM解析

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

React源码解析-Virtual DOM解析

React源码解析-Virtual DOM解析

我们看的ReactElement其实就是一个JavaScript对象,其参数主要为:$$typeof: REACT_ELEMENT_TYPE:这是ReactElement的唯一标识类似于唯一ID,用来后续寻找这个DOM对象;

key:开发者添加的唯一标识,目前我们没有添加;props:我们可以看的我们传入的DOM属性被分析成一个对象,成为ReactElement的一个属性;ref:是可以获取渲染后的DOM的引用,这里我们先忽略;

type:就是传入的标签名,我们看的我们传入的是div;_store:是在特殊情况下做一个备份,我们先忽略它;

单有一个对象可能还不太清晰,那我们再嵌套一个对象看一下;

React源码解析-Virtual DOM解析

React源码解析-Virtual DOM解析

可以看的,父元素的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对象生成与最终渲染之间,完成了其组件化的设计思想;这一点我们以后将会继续介绍;

上一篇:C#将制定文件夹下的PDF文件合并成一个并输出至指定路径


下一篇:flashbuilder发布release版本