当今流行的 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 # 创建新的应 ...
随机推荐
- mac下mysql5.6字符集设置
http://geeksblog.cc/2016/05/28/mac-mysql-unicode/ mac下mysql5.6字符集设置: 在mac下设置mysql5.6字符集时踩过的坑,百分百保证 ...
- \n 与 \r 在记事本中的内容表现方式 原创
总结:[0D,0A]的顺序才可以记事本才可以正常显示回车换行,其他EDITPLUS ,等编缉工具在下面三种情况下都可以换行 原始数据与表现形式 [0D,0A]序列才可以正常显示回车换行 --- ...
- 仿QQ聊天软件2.0版
地址:http://blog.csdn.net/u012027907/article/details/36952893 Oracle java
- Android(java)学习笔记170:Activity的生命周期
1.首先来一张生命周期的总图: onCreate():创建Acitivity界面 onStart():让上面创建的界面可见 onResume():让上面创建的界面 ...
- Vmare12(虚拟机)安装Mac OS X Yosemite 10.10
需要预备的软件如下: OSX10.10的系统镜像,下载好之后将后缀.cdr改成.iso,下载来源如下: 链接:http://pan.baidu.com/s/1sj4ri5R 密码:y86w un ...
- 使用Android Studio时so文件打包不到APK中
1,需要在build中添加如下配置,这是必备的 Android { sourceSets { main { jniLibs.srcDirs = ['libs'] ...
- CSS之关于clearfix--清除浮动
一,什么是.clearfix 你只要到Google或者Baidu随便一搜"css清除浮动",就会发现很多网站都讲到"盒子清除内部浮动时可以用到.clearfix" ...
- 将decimal类型的数值后面的0和.号去掉
今天在群里面看到有朋友在问如下的需求,想到以前在写项目时也遇到这种处理数值的需求,所以写一个例子贴在博客里. 需求:在许多显示货币值时,可能需要截取掉后面的0,显示小数值或者整型值. 举例:(1)数据 ...
- google code 上传源码
在使用google code 的时候 做个备份, git clone https://wushuangzilong@code.google.com/p/maplebanana-proxy/ git c ...
- spring quartz 多次调用
背景:公司项目有一个定时任务,每月1号0点执行,用到了spring的定时任务.发下定时任务调用的方法执行了俩次.测试部署的客户现场不会有问题 (测试的server.xml不会变化,除非本身提供的tom ...