react渲染和diff算法

1.生成虚拟domjavascript

createElement的做用就是生成虚拟dom。虚拟dom究竟是个啥,其实它就是个javascript对象~,这个对象的属性有props,vType,type, 而props也是个对象,它有children属性也有其余的,好比className,onClick之类的。java

2.虚拟dom转化成domnode

虚拟dom的vtype是3的时候对应的type是自定义组件,vtype是2的时候是对应的type是div之类的浏览器原生组件。算法

涉及到一个递归函数initVnode,initVnode接收一个参数:虚拟dom,返回一个参数dom。数组

a.若是是vtype等于3那么对应的type就是自定义的组件的构造函数,这时候,须要new一个自定义组件的对象,而后调用这个对象的render方法,浏览器

这个组件的render方法返回的仍然是个虚拟dom。 这时候就轮到递归上场了,调用本身去把这个虚拟dom转化成dom节点,并返回这个节点。app

b.若是是vtype等于2,那么对应的type是浏览器原生组件,这个时候就document.createElement(type),这里children有多是个虚拟dom数组,dom

遍历这个数组,用initVnode把虚拟dom转化成dom节点,再把dom节点appendChild到他们的父组件上,并返回父组件。函数

 

当调用render方法时,render会去调用一个map方法,根据传入参数的不一样,把被render的对象分为如下三类: 
* 文本 
* 原生 
* 自定义标签this

文本

对于文本,React会实例化一个文本节点的对象,而且调用该对象的mount方法。在这个mount方法中,把文本放到一个span中,调用容器组件的innerHTML,进行渲染。

原生标签

对于原生标签,React会实例化一个处理原生标签的对象,而且调用该对象的mount方法。在这个mount方法中,拼接一个字符串,而且不断递归上面的map方法,最后把拼接好的字符串放到容器组件的innerHTML中,进行渲染。

自定义标签

这个应该是你们最好奇的。自定义标签虽然叫标签,其实就是一个类。实例化一个处理自定义标签的对象后,首先React会处理自定义标签的生命周期方法,而后再次递归调用子组件的render方法进而调用map方法,直至把自定义标签分解为前两种标签。

更新

在调用this.setState()之后,也是调用了一个map方法,根据传入参数不一样,依然把要更新的标签分为文本、原生标签、自定义标签三类。具体处理过程以下。

文本

文本节点处理很简单,判断要更新后的文本与当前文本是否===,不是全等就删除原来文本,插入新文本。

自定义标签

对于自定义标签,首先根据对象的引用、key是否相同,判断是否须要更新。若是须要更新,就继续调用上述map方法进行子组件的更新。又是一个递归。可是注意,这里的map方法和渲染部分的map方法不是一个方法哟。

原生标签

对于原生标签,首先更新组件的属性,而后update子树,用diff算法来比较新的子树与目前标签的子树的不一样,造成一个差别树,而后用patch方法,把这个差别树更新到真正的DOM树上。

 

Diff算法

不一样类型结点:删除节点再建立

相同类型结点:直接改结点属性

列表结点:给结点加惟一标示key,减小dom操做

相关文章
相关标签/搜索