当今流行的 React.js 适用于怎样的 Web App?
React.js是Facebook开发的框架。
http://facebook.github.io/react/
官网上的描述是「A JavaScript library for building user interfaces」 React.js是用来构造UI的框架。不是一个framework,只是用来构造UI的library,提供MVC中View的机能。
采用了它进行开发的自然有Facebook本身,Instagram、Yahoo、Airbnb等等,是当今备受瞩目的library。
React.js的特征
为了了解React.js的特征,先与其他library或framework相比较。比如像Todo MVC这样对框架进行选型,以发送表单为例子进行实装试验。
jQuery
单纯jQuery的写法:
|
1
2
3
4
5
6
7
8
9
|
// 点了Submit之后
$('form').on('submit', functino() {
// 创建dom元素
var $li = $('<li>');
// ...
// 追加到list
$('ul').append($li);
});
|
可是,这样被DOM的结构所限制,要追加什么功能都非常麻烦,测试case也不好写。
Backbone.js
Backbone.js可以一定程度上解决类似问题。Backbone.js把管理数据的Model、与管理表现的View分开、然后把View分成各种组件来设计。比如下面这样:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var FormView = Backbone.View.extend({
onSubmit: function() {
// 创建data后只要追加到model
this.collection.add(data)
}
});
var ListView = Backbone.View.extend({
initialize: function() {
// model更新后追加到list
this.collection.on('add', this.render);
}
});
|
对FormView或ListView来说、都属于UI的一类功能、同类型的东西都只要调用组件就可以实现。
Backbone.js把数据和组件分开管理以后就更容易管理,但View的更新还需要手动来写仍然非常麻烦,Model与View之间传递事件也变得复杂,代码量扩大的时候就会出现很多问题。(和Backbone.js类似的library比如Marionette和Chaplin、本质上问题是一样的)
Angular.js、Vue.js
Angular.js、Vue.js为代表的、所谓MVVM系library的特征是数据一旦发生改变就会自动更新显示。
|
1
2
3
4
5
6
7
8
9
|
<form ng-submit="onSubmit()">
<input type="text" ng-model="text">
</form>
<ul>
<li ng-repeat="item in list">
{{item.text}}
</li>
</ul>
|
|
1
2
3
4
5
|
// Controller
$scope.onSubmit = function() {
// data更新后自动就显示了
$scope.list.push(newItem);
};
|
这样记录了HTML中用到的数据、JavaScript就自动把数据更新上去显示了。但是,这种类型的library在规模变大的时候要管理状态是很难的。
React.js
jQuery也好Backbone.js、Angular.js也罢,上面说了都不适应管理大规模的代码。虽然严谨的设计仍然可以成就方便管理的应用。但是,就违背了开发这些框架的本意,代码变得臃肿,设计也不简单。
React.js是规模再大也能提供便利管理的library。相反的,开发高速的小型应用Backbone.js或者Vue.js就更为合适。
React.js的特征是尽量做到组件无状态,便利的对组件进行管理:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var Form = React.createClass({
onSubmit: function() {
// 通知父级数据有更新
},
render: function() {
return <form onSubmit={this.onSubmit}>...</form>;
}
});
var List = React.createClass({
render: function() {
// 从父级拿到数据进行更新
return <ul>{this.props.list.map(...)</ul>;
}
});
|
各组件都从父级拿数据然后再去创建View。这一点很重要,组件自身不需要维持状态。通常根据从外部得到的输入进行输出或者测试的情况(大多数情况来自父级组件),管理和复用性都很高。
当然,全部组件都不维持状态的话与静态的HTML并无二致,有一些组件还是需要保持状态的。让尽量少的组件来维持状态,就是设计React.js的初衷。
通常是根节点组件在维持状态,它的子节点组件来传递:

然而,组件的状态一旦改变就会自动刷新树的结构,不需要手动操作,这与Angular.js之类是一样的。
数据一旦改变就自动显示的考虑也相同。

大部分根节点以外的组件都不用保持状态,用户的输入随着用户操作改变的话是需要维持自身的状态。
Virtual DOM
根节点组件保持了状态,它的状态一改变就刷新DOM树的设计非常单纯,一部分的改变导致整个DOM树的刷新影响性能。
这样React.js就引入了Virtual DOM的概念。
Virtual DOM粗略的说,就是构成DOM树的JavaScript对象、计算需要更新数据的对象后再实际更新最少需要更新的DOM元素。
React.js是用React.createClass创建组件,用render方法的返回值得到Virtual DOM。Virtual DOM是React.createElement创建而成的。
|
1
2
3
4
5
6
7
8
|
var MyComponent = React.createClass({
render: function() {
return React.createElement("div", {className: "foo"},
React.createElement("div", {className: "bar"},
"Hello ", this.props.name
)
);
});
|
而且,JSX使用独特的语法,用XML类似的语法来表现Virtual DOM。
|
1
2
3
4
5
6
7
8
9
10
11
|
var MyComponent = React.createClass({
render: function() {
return (
<div className="foo">
<div className="bar">
Hello {this.props.name}
</div>
</div>
);
}
});
|
用react-tools和babel这样的tool可以直接转换成JavaScript。
React.js的性能
有人觉得React.js速度很快,但真的是这样吗?采用了Virtual DOM以后,即便要更新根节点的数据也能最小限度的刷新DOM,确实应该是很快的,比刷新整个DOM树是要快很多。分三种情况进行性能测定:
- 用Backbone.js只刷新有变化部分的DOM
- 用Backbone.js当部分发生改变却刷新整个DOM树
- 用React.js当部分发生改变的时候用Virtual DOM计算好要改动的部分再更新DOM
结果如下图所示:

这样的话,React.js、Backbone.js只刷新部分DOM树明显是比刷新整个DOM树要快很多的。
如上所述,只让根节点保持状态是非常简单的设计,在这种简单设计的前提下同样提供比较好的性能,是React.js最大的特点。
Flux
Flux是Facebook非常提倡的一种应用架构设计。经常被拿来和MVC作比较、与MVC不同的是它的数据只有一个流向。
至此为止、作为React.js的设计理念、由根节点保持状态,一旦什么发生改变就刷新那个状态,不管怎样的变更都通知刷新,却不会知道具体是怎样的变更。
例如,DOM树的末端组件检测到用户的操作,需要刷新根节点的状态。这个时候,React.js中这个末端组件是无状态的,必须要立刻通过事件传递通知父级组件。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var Parent = React.createClass({
handleChange: function(changedData) {
// 子元素有什么需要更新的时候
},
render: function() {
// 设定子元素的事件处理函数
return <Child onChange={this.handleChange}>a</Child>;
}
});
var Child = React.createClass({
handleSubmit: function() {
// 父元素接收到事件进行处理
this.props.onChange(changedData);
},
render: function() {
// 设定表单的事件处理函数
return <form onSubmit={this.handleSubmit}>...</form>;
}
});
|
然而、用这种方法在嵌套较深的情况下更新组件时要传递给用来保持状态的根组件就非常的麻烦。那样,Flux中由View引起的变更进入Action(行为)然后通过Dispatcher(调度)之后Store(存储)后才能完成状态更新。
所谓Store是对数据的管理,相当于MVC模型中的M。View的根节点组件会读取Store中的变化,Store会自动更新数据。

Flux本身的设计理念是如此,实际应用却形形色色。Flux的原始设计是Facebook做的facebook/flux。是最小限度采用Dispacher的例子,其他实例还有如下一些:
总结
上文说明了React.js和Flux的设计思想和特征。React.js适用于有扩展需求的大型项目,却不适合敏捷开发小型应用。那样的需求采用Angular.js或者Vue.js的更多。静态的页面中少许UI单纯用jQuery也很便利。
实际上用过React.js和Flux写过应用就知道,组件要对应状态是一件很麻烦的事。然而,用这些麻烦的代价换来的是具有更强稳定性、更易维护的应用。
如果有这样的需求,还是值得考虑采用React.js的。
当今流行的 React.js 适用于怎样的 Web App?的更多相关文章
- 移动web端的react.js组件化方案
背景: 随着互联网世界的兴起,web前端开发的方式越来越多,出现了很多种场景开发的前端架构体系,也对前端的要求日益增高,早已经不是靠一个JQuery.js来做前端页面的时代了,而今移动端变化最大,近 ...
- 当今最流行的Node.js应用开发框架简介
快速开发而又容易扩展,高性能且鲁棒性强.Node.js的出现让所有网络应用开发者的这些梦想成为现实.但是,有如其他新的开发语言技术一样,从头开始使用Node.js的最基本功能来编写代码构建应用是一个非 ...
- 前端迷思与React.js
前端迷思与React.js 前端技术这几年蓬勃发展, 这是当时某几个项目需要做前端技术选型时, 相关资料整理, 部分评论引用自社区. 开始吧: 目前, Web 开发技术框架选型为两种的占 80% .这 ...
- 13个精选的React JS框架
如果你正在使用 React.js 或 React Native 创建用户界面,可以试一试本文推荐的这些框架. React.js 和 React Native 是流行的用户界面(UI)开发平台,且都是开 ...
- Facebook的Web开发三板斧:React.js、Relay和GraphQL
2015-02-26 孙镜涛 InfoQ Eric Florenzano最近在自己的博客上发表了一篇题为<Facebook教我们如何构建网站>的文章,他认为软件开发有些时候需要比较大的跨 ...
- 谈谈 React.js 的核心入门知识
近来React.js变得越来越流行,本文就来谈一谈React.js的入门实践,通过分析一些常用的概念,以及提供一些入门 的最佳编程编程方式,仅供参考. 首先需要搞懂的是,React并不是一个框架,Re ...
- 最流行的Node.js应用开发框架简介
最流行的Node.js应用开发框架简介 快速开发而又容易扩展,高性能且鲁棒性强.Node.js的出现让所有网络应用开发者的这些梦想成为现实.但是,有如其他新的开发语言技术一样,从头开始使用Node.j ...
- Angular、React.js 和Node.js到底选谁?
为了工作,程序员选择正确的框架和库来构建应用程序是至关重要的,这也就是为什么Angular和React之间有着太多的争议.Node.js的出现,让这场战争变得更加复杂,虽然有选择权通常是一件很棒的事情 ...
- React.js 学习笔记
React.js React.js 是时下最流行的前端 JavaScript 框架之一. 创建工程 # 安装 CLI $ npm install -g create-react-app # 创建新的应 ...
随机推荐
- cocos2dx 2.14使用UUID
1首先要清楚objective-c 与c/ c++混编的规则 关于c/c++/obj-c的混合使用 1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj ...
- WPF仿微软事件和属性窗体,效果更炫!
先看效果图:包含系统颜色.系统字体.支持自定义编辑窗体.集合绑定.提供多类型支持. 这是国外网站上无意中看到的,修改了下 感觉还不错!接下来大概介绍下 经过修修改改只留下了有用的主要部分: 前两项 ...
- linux 下ffmpeg和mencoder安装
ffmpeg和mencoder是进行视频转换和视频抽帧的重要开源工具,支持linux和windows环境下的视频转换和视频抽帧操作.本文章记录在linux这两者工具的安装过程.ffmpeg集成视频编码 ...
- linux64下安装swftools
在文档转换器中,需要在linux上安装swftools,经历了一番曲折过程终于安装成功.swftools安装包从http://www.swftools.org/download.html上面下载. 在 ...
- Spring声明式事务(xml配置事务方式)
Spring声明式事务(xml配置事务方式) >>>>>>>>>>>>>>>>>>>& ...
- python: pandas模块
10分钟入门 pandas 评:我跟作者的智商差距是有多大,才能让我用60分钟看完作者认为10分钟的内容... 详细内容见 Cookbook 习惯上我们先导入 : In [1]: import pan ...
- 总结如何实现Android浮动层,主要是dialog的使用
自定义一个类继承自Dialog类,然后在构造方法中,定义这个dialog的布局和一些初始化信息. 查看源码打印? 01 public class MenuDialog extends Dialog { ...
- 24、Javascript BOM
BOM(Browser Object Model)浏览器对象模型,一组浏览器提供的API. window对象 window对象表示当前浏览器的窗口,是Javascript的顶级对象,所有创建的对象.函 ...
- WebStrom安装了angularjs插件,但是没有语法提示
你必须要将angular.js文件放在当前工程下才能激活代码提示功能.
- jquery 单引号和双引号的区别及使用注意
在js中单引号和双引号都是一样的,平时使用的时候尽量用单引号,只有碰到嵌套的时候才会同时用两种引号,感兴趣的朋友可以了解下: 可以执行的语法:$("ul li a").filter ...