感受单向数据流模式reflux之美

为了简化react的flux带来的冗余操作,社区的同仁们给我们带来了很多优秀的轮子,诸如redux,reflux等。今天我们就通过逐行讲解代码实例的方法,感受一番reflux的设计之美。
Reflux是另一个实现Flux模式的库,旨在使整个应用架构变得更加简单。

准确地说,Reflux是由Facebook Flux演变而来(inspired by Facebook Flux),可以说是它的一个进化版本,自然而言就会拿两者进行比较
简要概括一下重点,就是:
1.Reflux保留了Facebook Flux中原有的三个概念:Actions、Stores、Views(Controller-Views),去除了Dispatcher,如果要用一张图表示的话,就是这样:

感受单向数据流模式reflux之美_第1张图片
1.jpg

这个例子是todo例子,学习语言从helloworld开始,学习框架从todo开始,这是我们码农界的文化传统!

感受单向数据流模式reflux之美_第2张图片
jmAFnye.gif

如图是我的项目目录

感受单向数据流模式reflux之美_第3张图片
Paste_Image.png

首先:我们要创建一个组件Component

var React =require("react");
var ReactDOM =require("react-dom");
var Reflux =require("reflux");
var ReactMixin =require("react-mixin");
var Actions =require("../anctions/anctions.js");
var Store =require("../stores/store.js");

var Todo=React.createClass({
   mixins: [Reflux.listenTo(Store,"onlist")],  //通过mixin将store的与组件连接,功能是监听store带来的state变化并刷新到this.state
   onlist(data){
       this.setState({
           list:data.list
       })
   },
   getInitialState() {
    return {
      list:[]
    }
  }, 
    componentDidMount(){
        Actions.getAll();
    },
     add(){ 
        var item =this.refs.item.value;
        this.refs.item.value="";
        Actions.add(item);
     },
     remove(i){
        Actions.remove(i);
     },
     render(){
         let items;
         if(this.state.list){
             items=this.state.list.map((item,i)=>{
                 return (
                     
  • {item.name}
  • ) }) } return (
      {items}
    ) } }) // ReactMixin.onClass(Todo, Reflux.connect(Store,"store")); var div=document.createElement("div"); div.id="app"; document.body.append(div); ReactDOM.render(,document.getElementById("app"));

    上述代码,我们干了3件事:

    渲染了一个组件,这个组件包括一个input,一个add按钮,一个列表,列表每项包含名称和remove按钮
    给这个组件添加了几个方法,其中 componentDidMount ()在组件渲染完成后触发, componentDidMount() 、add()和remove()方法分别调用actions的方法去更新状态
    最后一行代码,使用es6的mixin写法,使得组件监听store带来的state变化,并刷新界面。
    看到这里,很多没有接触过reflux的同学可能已经晕了,我来图解下reflux的功能流程吧!

    组件就是用户界面,actions就是组件的动作,store用于执行actions的命令,并返回一个state对象给组件。组件通过state来更新界面。

    这里我想说说react和angular的某个相同之处,就是将数据和界面绑定起来,通过操作数据来更新界面(不用苦逼的操作dom了)。我们把数据和界面的规则建好后,更新数据,界面自动就变化了。在这里,数据指的是this.state,界面指的是组件。

    那么为何要用actions和store这么多层去更新state呢?为了以后项目业务逻辑变复杂后便于管理。为什么便于管理,因为actions有很多钩子,钩子就是“触发之前,触发之后的回调什么的”,这些钩子我们以后会用得上。

    actions和store两个好基友开始更新状态

    actions/actions.js

    var Reflux = require('reflux');
    
    var Actions = Reflux.createActions([
        'getAll','add','remove'
    ]);
    
    module.exports = Actions;
    
    

    stores/store.js

    var Reflux =require("reflux");
    var Actions =require("../anctions/anctions.js");
    
    var Store= Reflux.createStore({
        items:[],
        listenables:[Actions],
        onGetAll(){
            this.trigger({list:this.items});
        },
        onAdd(item){
           this.items.push({name:item});
           console.log("oooooo",this.items);
           this.trigger({list:this.items});
        },
        onRemove(i){
             this.items.splice(i,1);
             this.trigger({list:this.items});
        }
    })
    
    module.exports = Store;
    
    

    上述代码,我们干了3件事:

    给数组对象的原型添加一个remove的方法,用于删除指定下标的元素
    创建一个store,监听actions的方法
    在store里,on开头的都是actions对应的回调函数,this.trigger(),负责更新state(这里指的是{list: this .items}这个对象 )

    最后,用webpack编译

    webpack.todo.config.js

    var htmlWebpackPlugin=require("html-webpack-plugin");  //自动生成html文件的插件
    var path =require("path");
    module.exports={
        entry:{
            todo_build:"./todo/app.js",
        },
        output:{
            path:"./todo_build/",
            filename:"[name].js"
        },
        module:{
            loaders:[
               {
                test:/.css$/,
                loaders:["style","css"],
                exclude:"/node_modules/"    
               },
               {
                test:/.jsx?$/,
                loaders:["react-hot","babel?presets[]=es2015&presets[]=react"],
                exclude:"/node_modules/",
                include: path.resolve(__dirname,"todo")
               }
            ]
        },
        resolve:{
            extensions:['','.js',".css",'jsx']  //自动补全识别后缀
        },
    
        plugins:[
            new htmlWebpackPlugin({
                title:"欢迎",
          //默认生成html文件
            })
        ]
    }
    

    总结
    相比较redux而言,

    reflux没有reducer的概念,取而代之,和action做基友的是store
    reflux没有把状态的一部分值绑定在组件的props上,而是将状态绑定在组件的state上,我们来看react dev tool的截图
    reflux可以直接调用action的方法,而redux必须将方法绑定在组件的props上,或者使用props的dispatch方法来执行actions的方法
    ……
    有此看来,reflux好理解的多,但是redux的单一state是实际项目中是非常好用的,所以,redux在github上的星星比reflux多得多!两个都是社区同仁智慧的结晶,都是优秀的值得学习的轮子!

    参考 http://www.tuicool.com/articles/bIBZnmF

    你可能感兴趣的:(感受单向数据流模式reflux之美)