《React-Native系列》22、 Flux框架Demo详解

来源:互联网 发布:3322软件站 编辑:程序博客网 时间:2024/06/16 03:02

今天我们来结合一个简单的Demo来讲解Flux框架,让大家了解Flux框架的真面目。

先上一张比较漂亮的图(对漂亮的图,总是没有抵抗力:-) )。


我们再来回顾下Flux框架的四大组成部分
  • View: 视图层
  • Action(动作):视图层发出的消息(比如mouseClick)
  • Dispatcher(派发器):用来接收Actions、执行回调函数
  • Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面

1、View


View很简单,我们定义了一个按钮,绑定了createNewItem方法,这个方法向Dispatcher发出一个名为addNewItem的Action。
[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. createNewItem: function (event) {  
  2.   ButtonActions.addNewItem('new item');  
  3. },  
  4.   
  5. var items = this.state.items;  
  6. var itemHtml = items.map(function (listItem, i) {  
  7.   return <li key={i}>{listItem}</li>;  
  8. });  
  9.   
  10. render: function() {  
  11.  return   
  12.   <div>  
  13.     <ul>{itemHtml}</ul>  
  14.     <button onClick={this.createNewItem}>New Item</button>  
  15.   </div>;  
  16. }  


2、Action


每个Action都是一个对象,都包含两部分:payload(数据)和 type(类型),type 是一个字符串常量,用来标识动作。
譬如:这里的type为ADD_NEW_ITEM
传递的数据为:text

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. var ButtonActions = {  
  2.   addNewItem: function (text) {  
  3.     AppDispatcher.dispatch({  
  4.       actionType: 'ADD_NEW_ITEM',  
  5.       text: text  
  6.     });  
  7.   },  
  8. };  

3、Dispatch


Dispatcher 的作用是将 Action 派发到 Store、。你可以把它看作一个路由器,负责在 View 和 Store 之间,建立 Action 的正确传递路线。
注意,Dispatcher 只能有一个,而且是全局的。

AppDispatcher.register()方法用来登记各种Action的回调函数。
譬如这里注册的:
[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. ADD_NEW_ITEM  
[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. UPDATE_ITEM  
[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. DELETE_ITEM  

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. AppDispatcher.register(function (action) {  
  2.   switch(action.actionType) {  
  3.     case 'ADD_NEW_ITEM':  
  4.       ListStore.addNewItemHandler(action.text);  
  5.       ListStore.emitChange();  
  6.       break;  
  7.     case 'UPDATE_ITEM':  
  8.       ...  
  9.       break;  
  10.     case 'DELETE_ITEM':  
  11.       ...  
  12.       break;  
  13.     default:  
  14.   }  
  15. })  
Dispatcher收到ADD_NEW_ITEM动作,就会执行回调函数,对ListStore进行操作。
记住,Dispatcher 只用来派发 Action,不应该有其他逻辑。

4、store

Store 保存整个应用的状态。它的角色有点像 MVC 架构之中的Model 。

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. var EventEmitter = require('events').EventEmitter;  
  2. var assign = require('object-assign');  
  3.   
  4. var ListStore = assign({}, EventEmitter.prototype, {  
  5.   items: [],  
  6.   
  7.   getAll: function () {  
  8.     return this.items;  
  9.   },  
  10.   
  11.   addNewItemHandler: function (text) {  
  12.     this.items.push(text);  
  13.   },  
  14.   
  15.   emitChange: function () {  
  16.     this.emit('change');  
  17.   },  
  18.   
  19.   addChangeListener: function(callback) {  
  20.     this.on('change', callback);  
  21.   },  
  22.   
  23.   removeChangeListener: function(callback) {  
  24.     this.removeListener('change', callback);  
  25.   }  
  26. });  
  27.   
  28. module.exports = ListStore;  

ListStore继承了EventEmitter.prototype,因此就能使用ListStore.on()和ListStore.emit(),来监听和触发事件了。
Store 更新后(this.addNewItemHandler())发出事件(this.emitChange()),表明状态已经改变。 View 监听到这个事件,就可以查询新的状态,更新页面了。

总结一句:
Store做的事情就是修改数据,发出change事件给View。
我们可以在Store声明任何的事件,只需要emit和on 监听和触发成对定义即可,不一定是change。

在View中,监听到Store 发出 change 事件,就会调用 this._onChange 更新组件状态,从而触发重新渲染。
[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. componentDidMount: function() {  
  2.   ListStore.addChangeListener(this._onChange);  
  3. },  
  4.   
  5. componentWillUnmount: function() {  
  6.   ListStore.removeChangeListener(this._onChange);  
  7. },  
  8.   
  9. _onChange: function () {  
  10.   this.setState({  
  11.     items: ListStore.getAll()  
  12.   });  
  13. },  


总结:
1、在一个简单的RN项目中,还是没有必要引入Flux框架,毕竟增加了项目的复杂度。
2、flux框架符合MVC模式,他的数据流转实际上使用消息机制来实现,譬如:EventEmitter里的emit 和on


参考:http://www.ruanyifeng.com/blog/2016/01/flux.html

0 0