React将DOM抽象为虚拟DOM,虚拟DOM其实就是用一个对象来描述DOM,经过对比先后两个对象的差别,最终只把变化的部分从新渲染,提升渲染的效率为何用虚拟dom,当dom反生更改时须要遍历 而原生dom可遍历属性多大231个 且大部分与渲染无关 更新页面代价太大html
当你使用React的时候,在某个时间点 render() 函数建立了一棵React元素树,
在下一个state或者props更新的时候,render() 函数将建立一棵新的React元素树,
React将对比这两棵树的不一样之处,计算出如何高效的更新UI(只更新变化的地方)
1、ReactDOM.render()前端
React最基本方法,react
用于将模版转换成HTML语言,渲染DOM,并插入指定的DOM节点中 git
该方法有3个参数 :github
- 模版的渲染内容(HTML形式) web
- 须要插入的DOM节点 算法
- 渲染后的回调(通常用不到)app
// 1. 导入 react import React from 'react' import ReactDOM from 'react-dom' // 2. 建立 虚拟DOM // 参数1:元素名称 参数2:元素属性对象(null表示无) 参数3:当前元素的子元素string||createElement() 的返回值 const divVD = React.createElement('div', { title: 'hello react' }, 'Hello React!!!') // 3. 渲染 // 参数1:虚拟dom对象 参数2:dom对象表示渲染到哪一个元素内 参数3:回调函数 ReactDOM.render(divVD, document.getElementById('app'))
var Hello = React.createClass({ render: function() { return <div>Hello Taobao, Hello UED</div>; } });
ReactElement.createElement = function(type, config, children) { ... }
如咱们在jsx中描述的 < Hello /> ,编译后就是 React.createElement(Hello)dom
3. createFactory,经过工厂方法建立React组件实例,在js里要实现工厂方法只需建立一个带type参数的createElement的绑定函数:ReactElement.createFactory = function(type) { var factory = ReactElement.createElement.bind(null, type); return factory; };
var h = React.createFactory(Hello);
h({x:1})
h({x:2})
h({x:3})
在使用React.createClass以前,咱们先来看官方给出的解释函数
ReactClass createClass(object specification)
建立一个给出说明的组件类(这个给出的说明也就是其参数 object specification)。这个组件实现一个render方法,而且render方法返回一个单一的节点。这个返回的节点可能包含任意深度的子节点结构。该方法与标准的原型类不一样的地方就是不用使用new去实例化对象。这些组件被很好的封装起来,能够很好的为你建立后台实例。
固然,单看这些定义我是不知道该如何去使用createClass方法的(我觉的我翻译的不够标准)。那下面咱们直接经过一个实例来解释如何使用React.createClass()。
在本篇文章,咱们只是实现render方法,而且在介绍应该注意的问题。对于object specification的详细介绍,那就涉及到了组件的详细说明和生命周期的知识,在本篇咱们不作介绍。
例一
var Root = React.createClass({
render:function(){
return (
<h1>迹忆博客</h1>
);
},
});
ReactDOM.render(
<Root />,
document.getElementById('content')
);
这是一个简单的例子。虽然说简单,可是有两个须要注意的地方。
第一点就是生命的Root首字母必须大写,也就是说咱们若是将Root 写成root,那么<root />就会被直接解析成html标签(<root></root>)。下面咱们来看以下的代码(下面的代码是错误的)
var root = React.createClass({
render:function(){
return (
<h1>迹忆博客</h1>
);
},
});
ReactDOM.render(
<root />,
document.getElementById('content')
);
其解析的结果以下
<root data-reactid=".0"></root>
显然这不是咱们想要的结果。
第二点是,在一个createClass建立的组件中只能有一个根节点。这个根节点能够有任意层的子节点。下面咱们看以下的代码
var Root = React.createClass({
render:function(){
return (
<h1>迹忆博客</h1>
<a>www.onmpw.com</a>
);
},
});
ReactDOM.render(
<Root />,
document.getElementById('content')
);
这段代码也是存在错误的,在解析过程当中会报以下的错误
SyntaxError: embedded: Adjacent JSX elements must be wrapped in an enclosing tag (22:18) 20 | return ( 21 | <h1>迹忆博客</h1> > 22 | <a>www.onmpw.com</a> | ^ 23 | ); 24 | }, 25 | }); ...("+loc.line+":"+loc.column+")";var err=new SyntaxError(message);err.pos=pos;err....
所以若是咱们想要实现上述咱们想要的结果,能够在h1和a的外面再加一层节点。以下
例二
var Root = React.createClass({
render:function(){
return (
<div>
<h1>迹忆博客</h1>
<a>www.onmpw.com</a>
</div>
);
},
});
ReactDOM.render(
<Root />,
document.getElementById('content')
);
这样就能保证一个组件中只有一个根节点,又能实现咱们想要的效果。
其实对于render来讲,该方法会返回一个React组件树,用来接受该组件树的变量名称必须首字母大写。而且该组件树只能有一个根节点,这也是符合实际状况的。最终这棵组件树会被ReactDOM.render渲染成HTML标签。
对于例二中的<div>标签,它并非一个真正的DOM节点,而是一个虚拟的DOM节点。你能够这样认为,组件树中的这些节点就是一些标记或者数据,只是React知道该如何处理这些标记或者数据。
其实React.createClass的知识点不少,这里我只是简单介绍在使用过程当中应该注意的问题。