React实战-如何构建React+Flux+Superagent的完整框架
React实战-如何构建React+Flux+Superagent的完整框架
ReactJS并不像angular一样是一个完整的前端框架,严格的说它只是一个UI框架,负责UI页面的展示,如果用通用的框架MVC来说,ReactJs只负责View了,而Angular则是一个完整的前端框架,包含了MVC的全部。那么问题来了,采用ReactJS时,M和C怎么办了,其实不仅是M和C的问题,包括UI控件的如何选择,开发者都有很大的主动权,但是任何事情总在两难的选择中,全帮你做了,面面面具到,你会觉得受约束,这么不好,那也不好,还不方便用别的,选择多了也是问题,到底哪一款才是最好的。
在ReactJs的官网上推荐的是React+Flux,但是现在越来越流行的是React+Redux。其实Redux是Flux的升级版,使得一些写法和应用更加简单,如果你熟悉了React+Flux的方式,你能很容易的使用React+Redux了。
在访问服务端时,你依然可以选择你喜欢的组件来实现,jQuery等都可以选择,但是Superagent是个不错的选择,简单、精炼、并且访问操作RestFul服务非常方便。
整个框架依据ReactJs的单项数据流方式,如下图:
图中View自然就是ReactJs的页面组件了。整个框架的结构也基本依据上图构建。
分为View(Components)、Dispatcher、Actions、Store和Resource
View:页面组件;
Dispatcher:管理注册分发事件;
Actions:定义各类操作;
Store:关联事件与操作,调用Resource,获取数据,并触发相关事件;
Resource:访问服务,获得数据。
整个框架结构清晰明了,还是简单粗暴的上代码直观(进入页面,显示列表数据)。
1.View
function getAllProducts() {
return \{
allProducts: ProductStore.getProducts() || null
\};
};
var ProductCategoryRow = React.createClass({
getInitialState: function () {
return \{
allProducts: ProductStore.getAllProducts() || null
\};
\},
componentDidMount(){
ProductStore.addChangedListener(this.\_onChange);
ProductAction.getAllProducts();
\},
componentWillUnmount()\{
ProductStore.removeChangedListener(this.\_onChange);
\},
\_onChange()
\{
this.setState(getAllProducts());
\},
render: function() {
return (<tr><th colSpan="2">\{this.props.category.name\}</th></tr>);
}
});
var ProductTable = React.createClass({
render: function() {
This.state.allProducts.forEach(function(product) \{
rows.push(<ProductCategoryRow category=\{product\} key=\{product.id\} />);
\});
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>\{rows\}</tbody>
</table>
);
}
});
2.Dispatcher
var Dispatcher = require(‘flux’).Dispatcher;
var ProductDispatcher = new Dispatcher();
module.exports = ProductDispatcher ;
3.Actions
module.exports = {
getAllProducts: function () {
ProductDispatcher.dispatch(\{
type: “getProduct”
\});
}
};
4.Store
var EventEmitter = require(‘events’).EventEmitter;
var assign = require(‘object-assign’);
var CHANGE_EVENT = ‘change’;
var RulesStore = assign({}, EventEmitter.prototype, {
getProducts(){
return this.products;
},
searchProducts(){
ProductResource.getProducts().then((products) => {
This.products = products;
}
this.emit(CHANGE_EVENT);
}
addChangedListener(callback)
{
this.on(CHANGE\_EVENT, callback);
},
removeChangedListener(callback){
this.removeListener(CHANGE\_EVENT, callback);
},
}
ProductDispatcher.register(function (action) {
switch (action.type) {
case “getProduct”:
RulesStore.searchProducts();
break;
Default:
Break;
}
}
5.Resource
module.exports = {
getProducts(productid){
this.get(‘/admin/rules/‘)
.set('Content-Type', 'application/XXXX')
.query('productid=' + productid)
.then(this.resolve, this.reject);
}
}
上述代码完整的展现了一个基于ReactJS+Flux的框架,部分出于隐私考虑没有写出来。
还没有评论,来说两句吧...