React缺点:只是一个UI组件,很难应用在大型的应用中,因此需要搭配合适的前端框架,即:React+前端框架=大型应用;
flux:是一个单向数据流动的架构,主要由四部分组成:action+store+dispatcher+view;
view:是一个控制器角色的视图;
action:是用来作为数据传递的途径;
dispatcher:分配器,将action分配到对应的store,并触发回调(充当路由器);
store:数据和逻辑部分(模块);
流程图:
注意:store,action,dispatcher都单独封装成一个模块,然后在主组件中调用;
过程:
1)制定action,分配给dispatcher;
2)视图通过用户的交互触发action;
3)action传到dispatcher,由dispatcher发配到注册所有的callback中;
4)store通过callback从action中更新了data,并触发change事件;
5)调用了setstate方法,从而更新了视图;
A)dispatcher:
功能:将接收到的action分配到store中;
特点:
1)将dispatcher创建实例来调用;
2)一个应用中只能存在一个dispatcher实例;
3)dispatcher只充当分派角色,不涉及逻辑操作;
4)dispatcher输出为一个类;
主要用到的API:
register(callback):在dispatcher中注册一个回调;
dipatch(object):将action分配到所有注册的回调函数中;
B)Action:
定义:每个组件的行为都可以定义为一个action对象;
构成:action对象=actionType(行为类型)+playload(数据)[+others];
用法:利用dispatcher实例的dispatch将action传递到所有注册的回调函数中;
C)store:
定义:是用来更新,保存数据,设计逻辑操作的一个对象;
功能构成:
1)保存,更新数据;
2)将该对象绑定一个change事件(在componentDidMount中调用);
3)解除对象的change事件(在componentWillUnMount中调用);
4)发射change事件(在dispacher注册的callback中调用);
设计到的模块:
events模块:该模块的eventemitter提供on,remove,emit方法;
object-assign模块:将几个对象合并,返回新的对象;
注意:change事件是绑定在dom上,二是所绑定的对象接收到change事件后,执行callback中,调用了setstate,从而让组件更新,效果就跟组件绑定了change事件一样;
D)view:
定义:讲几个模块,子组件集中调用在此组件中,是充当一个容器的作用;
更新的流程:
视图------action--------通过dispatch方法传到dispatcher的register中----------保存到store----------发射事件----------组件中的store监听----------执行回调中的setstate方法-----更新视图
源代码:
view:
/*组件功能,点击有文字出现在文本框*/ var myAction=require("ButtonAction"); var myStore=require("ButtonStore"); var Button=React.createClass({ render:function(){ return ( <div> <input type="text" /> <input type="button" onClick={this.props.onClick}/> </div> ) } }); //控制器组件 var Controller; Controller = React.createClass({ getInitialState:function(){ return{ data:myAction.data } }, componentDidMount:function(){ myStore.addChangeListener(this.actionChange); }, componentWillUnmount:function(){ myStore.removeChangeListener(); }, actionChange:function(){ this.setState({data:myStore.getData()}); }, hand: function(){ myAction.dispatchAction("shiyanlizi"); }, render: function () { return ( <Button onClick={this.hand}></Button> ) } }); ReactDOM.render(<Controller></Controller>,document.getElementById("one"));action:
var myDispatcher=require("ButtonDispatcher"); var myAction={ createAction:function(){ return { actionType:"click_action", playload:arguments[0] } }, dispatchAction:function(text){ var action=this.createAction(text); myDispatcher.dispatch(action); } }; module.exports=myAction;dispatcher:
var dispatcher=require("dispatcher"); var myStore=require("ButtonStore"); var myDispatcher=new dispatcher(); myDispatcher.register(function(action){ switch (action.actionType){ case "action_click": myStore.addData(action.playload); myStore.emitChange(); break; default : break; } }); module.exports=myDispatcher;store:
var emitter=require("events").EventEmitter; var assign=require("object-assign"); var myStore=assign({},emitter.prototype,{ data:[], getData:function(){ return this.data; }, addData:function(text){ this.data.push(text); }, addChangeListener:function(callback){ this.on("change",callback); }, removeChangeListener:function(){ this.remove("change"); }, emitChange:function(){ this.emit("change"); } }); module.exports=myStore;(以上就是我的理解和自己写的代码,时间紧凑,若有细节错误,请谅解)