<meta charset="utf-8">
经过这段时间的学习和实践,对React有了一定的了解,谨以此文记录自己对React的认识。如有不妥之处,欢迎批评指正。
React的三项核心技术:
- 虚拟DOM
- 响应式UI
- 组件
一、虚拟DOM
- DOM(Document Object Model)
说到虚拟DOM,我们先来回顾一下什么是DOM。在《JavaScript DOM 编程方法》中的定义是:DOM是一套对文档的内容进行抽象和概念化的方法。简而言之,它是文档对应的对象模型,DOM把一份文档(以HTML为例)表示为一棵树,在DOM中,文档是由节点构成的集合,而节点又分为不同的类型,元素(element)节点、文本(text)节点、属性(attribute)节点。DOM就是为了操作HTML中的元素,例如我们常用的的getElementById(),就是DOM中的一个方法。DOM不是一种编程语言,但是我们用JS对网页进行的所有操作都是通过DOM进行的。用户在网页看到的内容是开发者告诉DOM应该表现成什么样子,jQuery 和 React 都是库,开发者使用它们作为与 DOM 交流的工具。
我们知道,浏览器的工作流是:创建DOM树、创建渲染树、布局、绘制。每一次的每一次的 DOM 操作,都会引发一次从创建 DOM 树、创建渲染树、布局到绘制的全过程,尤其是在创建渲染树阶段,对节点样式的计算量通常很大。而正常的,由用户引发的页面改变往往不止一次的 DOM 操作,多次计算,将导致页面性能大幅降低。在之前的jQuery开发中我发现一旦DOM操作比较复杂,需要花大量时间理清他们之间的联系,而且DOM操作引发的重复计算会导致页面的渲染等待时间会变长。
- 虚拟DOM
相比于操作真实DOM,React的虚拟DOM就能展示它在速度上的优势了。React是开发者和DOM树之间的中间人,它简化了二者的沟通成本,还会用虚拟DOM来速写真实DOM,开发者只用不停地告诉React他的要求,React会在草稿中快速记录下所有细节并在合适的时候拿给DOM树看。React十分机智,它会对草稿进行去重和对比筛选出最终样板后展示给DOM树,让他能够付出最小的工作量根据要求展示出需要的样子。
一开始对虚拟DOM的理解停留在:通过JavaScript对象模拟原生DOM,加上DOM Diff 极大提升了DOM操作的性能。然而,虚拟DOM最大的意义不在于性能的提升,而在于对DOM进行了一层抽象。它在UI和代码之间建立了一个隔离层,减少了逻辑和试图的耦合性,提高了代码的可移植性和可维护性。
<meta charset="utf-8">
3787429224-56fe77fe0965e_articlex.png二、响应式UI
使用 jQuery 来更新 DOM需要在适当的时机以正确的顺序来指定要更改的元素,React可以通过改变应用中的数据来改变React应用的状态,React应用中的每一部分都使用props(外部传入)和states(本身)两个属性来储存状态。state属性产生于ReactElement的内部,可传递到子ReactElement中作为props。这两者的差异就好比小时候我妈每天要打电话告诉我明天穿什么衣服的时候,之前的描述是你先穿哪件秋衣,再套哪件马甲,再穿哪个外套,现在她只用拍张照告诉我她的搭配,我自己去穿就好。
用数据去驱动组件状态的变化,开发者专注于数据部分,当数据不变时只有一种对应的界面, 因而程序有着更好的可预测性。
三、组件
- 基本思想
React从功能的角度出发,将用户界面上每一个功能相对独立的模块定义成组件,然后将小组件通过组合或嵌套的方式构成大组件,最终完成整体UI的构建。对比MVC的将模型—视图—控制器定义成不同的类,实现表现,数据,控制的分离,组件化开发模式的思想是用户界面功能模块间的分离,从功能的角度出发,将用户界面分成不同的组件,每个组件都独立封装。这样做的好处有,一个复杂的UI可以拆分成多个简单的UI组件;每个组件都是具有独立功能的,可用于多个场景;每个小组件仅包含自身的逻辑,更容易被维护。React里将组件看成一个状态机,先设置初始状态,在用户的操作使得状态属性发生改变时,会重新渲染用户界面,而且会向下遍历整棵组件树,重新渲染使用该属性的组件。
- 函数组件和类组件
React有两种组件,函数组件(Functional Components) 和类组件(Class Components),我观察到在实际工程中大量使用了类组件,在了解了函数组件的试用场景和功能实现之后,此处要好好pick一下。
函数组件是纯展示组件,这种组件无法使用State,也无法使用组件的生命周期方法,因此它只负责根据传入的props来渲染DOM,不涉及到state状态的操作。函数组件是无状态的,因此就不会有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升,同时也就不能访问this对象。
屏幕快照 2018-08-05 下午4.59.01.png从以上的定义方式我们可以看出声明简洁,代码量少。函数组件不需要声明类,可以避免大量的譬如extends或者constructor这样的代码;不需要声明this,也不需要将函数的this关键字绑定到当前作用域。因此如果开发中组件仅仅需要展示,尽量使用函数组件。
类组件是React推荐的组件定义方式,React 升级到 v0.13 后就支持了 ES6 的class语法,我们可以使用class App extends React.Component{…}的方式创建组件,这也是目前官方推荐创建有状态组件的方式。React.Component创建组件时,事件函数并不会自动绑定this,需要我们手动绑定,不然this将不会指向当前组件的实例对象。以下有三种手动绑定方法:在构造函数中完成绑定;在调用时使用method.bind(this)来完成绑定;使用arrow function来绑定。
- 组件间通信
我们知道React是单向数据流,数据主要从父节点通过props传递到子节点。如果顶层(父级)的某个props改变了,React会重渲染所有的子节点。不可以使用this.props直接修改props,因为props是只读的,props是用于整个组件树中传递数据和配置。state和props的区别在于前者只存在于组件内部,只能从当前组件调用this.setState修改state值。
父组件向子组件传递直接通过props。子组件向父组件通信可以通过在父组件里声明回调函数,通过props传递给子组件,子组件调用该函数,把要传递的内容通过参数传给父组件。兄弟间通信可以借助共同拥有的父组件,而如果兄弟组件都是最高层的组件,为了能够让它们进行通信,必须在它们外层再套一层组件,这个外层的组件起着保存数据,传递信息的作用,这其实就是redux所做的事情。
因为之前的前端开发一直使用jQuery,对比了两者,在此我要为jQuery多说几句:
- React并不适合所有项目,需要结合实际情况综合考虑
- jQuery与React并不是一个层面上的东西,jQuery只是一个工具库,这里只是展示两种编程模式的思维差异。React适合用在那些DOM操作复杂的单页面应用,jQuery则是个用来帮你完成一些基本操作的工具库
- 理解一个技术的思想比学会怎么用它更重要,同时我们还需要知道不同的技术间的区别的核心在哪,这样我们才能学会用合适的技术去解决合适的问题
- jQuery可以写出非常简洁的代码。但是必须想出良好的代码结构,每次想要增加新功能的时候还需要特别注意是否影响代码的重构,使用React会帮助团队内部拥有更好的代码结构,页面性能也会得到相应的提高
网友评论