ReactJS入门(一)—— 初步认识React
React刚开始红的时候,由于对其不甚了解,觉得JSX的写法略非主流,故一直没打算将其应用在项目上,随着身边大神们的科普,才后知后觉是个好东西。
好在哪里呢?个人拙见,有俩点:
1. 虚拟DOM —— 在DOM树的状态需要发生变化时,虚拟DOM机制会将同一Event loop前后的DOM树进行对比(自然通过一系列高效的算法),如果俩个DOM树存在不一样的地方,那么React仅仅会针对这些不一样的区域(DOM diff)来进行响应的DOM修改,从而实现最高效的DOM操作和渲染。
如下图,我们修改了DOM树上一些节点(或UI组件)对应绑定的state(不知道state是什么没关系,后续我们会提及),React会即刻将其标记为“脏状态”,在一个Event loop结束时(即使过程中你对某个组件的state进行了多次修改),React会计算得出DOM树上需要修改的地方(“脏”了的地方,如下图红点)及其最终的状态,并仅仅针对这些地方进行一次性的重新渲染。
于是好处显而易见,并非每修改一次组件的state,就会重新渲染一次,而是在Event loop结束后做一次“秋后算账”,减少冗余的DOM操作。另外React只针对需要修改的地方来做新的渲染,而非重新渲染整个DOM树,自然效率很是不错。
2. 组件可嵌套,而且,可以模版化嘛 —— 其实在React里提及的“组件”,常规是一些可封装起来、复用的UI模块,说的接地气了可以理解为“带有细粒度UI功能的部分DOM区域”。然后我们可以把这些组件层层嵌套起来使用(当然这样组件间会存在依赖关系)。
至于模块化,类似于ejs那样可以作为独立的模块被引用到页面上来复用,不过咧,它可以直接把UI组件当作脚本模块那样来使用,咱完全可以配合CommonJS、AMD、CMD等规范来require需要的组件模块,并处理好它们的依赖关系(是不是碉堡了)。
基于上述的俩点,自然的也打算投入React怀抱了。不过在这之前得先理清俩点事情:
1. React是一个纯View层,不擅长于和动态数据打交道(哎哟咱也不谈Flux了,Flux的概念其实也不完善),因此它不同于,也替代不了常规的MV*框架;
2. React很擅长于处理组件化的页面,在页面上搭组件的形式有点像搭乐高一样,因此用上React的项目需求常规为界面组件化。另外React只支持到IE8+,就天朝的情况,是否使用React还是得稍微斟酌一番。
唠嗑了这么多,下面开始进入React的入门课程。本章提及的代码都可以在我的Github上下载到。
JSX
JSX是React编写组件的一种语法规范,可以看为是js的扩展,它支持将HTML和JS混写在一起,最终会通过React提供的 JSXTransformer.js 来将其编译为常规的js,方便浏览器解析。我们来个最简单的例子:
DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>最简单的jsxtitle>
<script src="react.js">script>
<script src="JSXTransformer.js">script>
head>
<body>
<div id="a">123div>
<script type="text/jsx">
var name = 'VaJoy';
React.render(<h1>{name}</h1>, document.getElementById('a'));
script>
body>
html>
页面上我们引入了 react.js 和 JSXTransformer.js 俩个重要的脚本,前者自然是react的核心,后者则是将JSX语法转为js语法。
实际上使用 JSXTransformer.js 在客户端来解析JSX语法是一件冗余、耗性能的事情,我们可以在上线项目之前,事先使用诸如 gulp-react 的工具先把所有的JSX均转换为js文件再引入到页面中。
当然如果你掌握了react的JS写法(当然相比JSX的学习成本要高不少),你可以直接在页面上书写相应的 原生js 即可,来个对比:
//使用JSX React.render(, document.getElementById('example') ); //不使用JSX React.render( React.createElement('div', null, React.createElement('div', null, React.createElement('div', null, 'content') ) ), document.getElementById('example')content
回到开头第一段代码段,我们将页面的JSX直接写在