今天看啥  ›  专栏  ›  Xiaowei

React实现-介绍和准备

Xiaowei  · 掘金  ·  · 2018-07-24 06:24
阅读 18

React实现-介绍和准备

logo-og

为什么要实现一个React?如果你进来看了这篇文章,相信你我的想法是一致的,为了更好的理解和使用React。这一篇是这个文章系列的第一篇,主要说下实现React之前需要掌握和明白的地方,不单单是介绍,请耐心看完。这个系列需要足够的耐心去看,静下心来才能有更大的收获。本系列文章参考dialact系列文章,你可以直接去看dialact,它也足够精简。这个系列中我会调整部分结构来帮助理解。

预备知识

在React的实现中,有几种写法需要了解。

为dom元素添加Attribute

var dom = document.getElmentById('root');
dom['className'] = 'container'
dom['style'] = 'background-color: red';
复制代码

我们这里使用直接赋值的方法,而不是使用setAttribute来给dom添加Attribute,是为了保证只有有效的Attribute才能被赋值。这里涉及到attributeproperty的区别。

attribute和property的区别

attribute描述xml中的附加值如

<apple name='apple'></apple>
复制代码

这里的name就是attributeproperty在js中描述的是对象的属性如

var person = { name: 'chris' }
复制代码

这里的nameproperty

对于dom元素来说,它是一个HTMLElement类型的对象,它有很多property,在其property中有一个attributes属性,该属性是NameNodeMap类型,用来存储html展示的attributes

当我们使用setAttribute函数时,会直接为attributes赋值,不论其名称如何。而如果我们使用dom['property'] = value的形式的时候,它会根据名称寻找和attributes之间的对应关系,如果有对应则在赋值的同时为dom添加attribute,如果没有则只添加property而不会添加attribute

propertyattribute之间的对象关系根据不同的元素类型来确定,同时对应名称也不是一定相同,如

// property => attribute
style => style
className => class
htmlFor => html
复制代码

其他要用到的方法

// 为元素绑定事件
dom.addEventListener('click', function() {});

// 为文本节点赋值
dom['nodeValue'] = value;

// 寻找节点
var dom = document.getElementById('root');

// 创建节点
var dom = document.createElement('div');

// 创建文本节点
var dom = document.createTextNode('');
复制代码

jsx

jsx的本质是一个语法糖,例如有如下jsx语法

<div className="container">
	<h1>hello world</h1>
</div>
复制代码

在React中会被解析成如下形式:

React.createElement({
	type: 'div',
	props: {
		className: 'container',
		children: [
			React.createElement({
				type: 'h1',
				children: ['hello world']
			})
		]
	}
})
复制代码

这个转换我们可以借助babel-plugin-transform-react-jsx来帮助我们实现,我们所需要做的就是实现React.createElement

diff

由于操作dom要付出的代价很大,React最大限度的来利用已经生成的dom,避免重复渲染。React中用到了虚拟dom的概念,它其实就是一个对象,类似于我们上面jsx中写到的

{
	type: 'h1'
	children: ['hello world']
}
复制代码

实际的React中更加复杂,配合diff算法可以减少dom操作。传统比较两棵树的算法是O(n^3),React有两个假设:

  • 不同类型的节点会产生不同的树
  • 开发者能够通过赋值key属性来区分列表中不同的节点

在这两个假设的基础上,React只需要比较两棵dom树中同一层对应的节点就可以,将算法复杂度降低到O(n),同时能覆盖到绝大部分的情况,这种diff算法在React中被称作Reconciliation

下一篇,我们开始实现我们自己的React。接下来我会持续更新,这是github原文地址,欢迎star,欢迎watch。




原文地址:访问原文地址
快照地址: 访问文章快照