为了简化react的flux带来的冗余操作,社区的同仁们给我们带来了很多优秀的轮子,诸如redux,reflux等。今天我们就通过逐行讲解代码实例的方法,感受一番reflux的设计之美。

例子

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

组件

components/todo.js

import React from 'react'
import Reflux from 'reflux'
import ReactMixin from 'react-mixin'
import store from '../stores/store'
import actions from '../actions/actions'

export default class Todo extends React.Component{

  //组件渲染完成后,通过action获取所有的数组,刷新绑定到this.state上
  componentDidMount() {
    actions.getAll();
  }

  add(){
    var item =this.refs.item.value;
    this.refs.item.value='';
    actions.add(item);

  }

  remove(i){
    actions.remove(i);
  }

  render() {
    //items用于乘放li的集合
    let items;
    if(this.state.list){
      items=this.state.list.map( (item,i)=> {
              //设置key是因为react的diff算法,是通过key来计算最小变化的
              return <li key={i}>
                {item.name}
                <button onClick={this.remove.bind(this,i)}>remove</button>
              </li>
            })
    }
    return (
        <div>
          <input type="text" ref="item"/>
          <button onClick={this.add.bind(this)}>add</button>
          <ul>
            {items}
          </ul>
        </div>
    )
  }
}

// ES6 mixin写法,通过mixin将store的与组件连接,功能是监听store带来的state变化并刷新到this.state
ReactMixin.onClass(Todo, Reflux.connect(store));

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

  1. 渲染了一个组件,这个组件包括一个input,一个add按钮,一个列表,列表每项包含名称和remove按钮
  2. 给这个组件添加了几个方法,其中componentDidMount()在组件渲染完成后触发,componentDidMount()、add()和remove()方法分别调用actions的方法去更新状态
  3. 最后一行代码,使用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

import Reflux from 'reflux'

export default Reflux.createActions(['getAll','add','remove']);

stores/store.js

import Reflux from 'reflux'
import actions from '../actions/actions'

//给数组添加remove方法,用于去除指定下标的元素
Array.prototype.remove=function(dx)
{
    if(isNaN(dx)||dx>this.length){return false;}
    for(var i=0,n=0;i<this.length;i++)
    {
        if(this[i]!=this[dx])
        {
            this[n++]=this[i]
        }
    }
    this.length-=1
};

export default Reflux.createStore({
    items:[],
    //监听所有的actions
    listenables: [actions],
    //on开头的都是action触发后的回调函数
    onGetAll () {
        //更新状态(就是个对象)
        this.trigger({list:this.items});
    },
    onAdd(item){
        this.items.push({name:item});
        this.trigger({list:this.items});
    },
    onRemove(i){
        this.items.remove(i);
        this.trigger({list:this.items});
    }
});

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

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

渲染组件

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Todo from './components/todo';

ReactDOM.render(
  <Todo>
  </Todo>,
  document.querySelector('#app')
);

最后,用webpack编译

webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: {
        app:path.join(__dirname, 'src'),
        vendors: ['react','reflux','react-mixin']
    },
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        loaders: [
            {
                test:/\.js?$/,
                exclude:/node_modules/,
                loader:'babel',
                query:{
                    presets:['react','es2015']
                }
            }
        ]
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js')
    ]
};

总结

相比较redux而言,

  1. reflux没有reducer的概念,取而代之,和action做基友的是store
  2. reflux没有把状态的一部分值绑定在组件的props上,而是将状态绑定在组件的state上,我们来看react dev tool的截图
  3. reflux可以直接调用action的方法,而redux必须将方法绑定在组件的props上,或者使用props的dispatch方法来执行actions的方法
  4. ……

有此看来,reflux好理解的多,但是redux的单一state是实际项目中是非常好用的,所以,redux在github上的星星比reflux多得多!两个都是社区同仁智慧的结晶,都是优秀的值得学习的轮子!

源代码:

https://github.com/lewis617/react-redux-tutorial/tree/master/todo-reflux

运行方法:

npm install

npm run build

手动打开index.html


教程源代码及目录

如果您觉得本博客教程帮到了您,就赏颗星吧!

https://github.com/lewis617/react-redux-tutorial

react+reflux入门教程的更多相关文章

  1. 基于Nodejs生态圈的TypeScript+React开发入门教程

    基于Nodejs生态圈的TypeScript+React开发入门教程   概述 本教程旨在为基于Nodejs npm生态圈的前端程序开发提供入门讲解. Nodejs是什么 Nodejs是一个高性能Ja ...

  2. React Native入门教程 3 -- Flex布局

    上一篇文章中介绍了基本组件的使用 React Native入门教程(笔记) 2 – 基本组件使用及样式 本节内容将继续沿用facebook官方例子介绍如何使用Flexbox布局把界面设计的多样化. 转 ...

  3. React Native入门教程2 -- 基本组件使用及样式

    在上一篇文章中,我们学会了如何搭建React Native的环境(React Native入门教程(笔记) 1 – 开发环境搭建),不知道你们是否搭建好了呢,如果还没有,那么快动起小手,来体验RN带给 ...

  4. React Native入门教程 1 -- 开发环境搭建

    有人问我为啥很久不更新博客..我只能说在学校宿舍真的没有学习的环境..基本上在宿舍里面很颓废..不过要毕业找工作了,我要渐渐把这个心态调整过来,就从react-native第一篇博客开始.话说RN也出 ...

  5. React实例入门教程(1)基础API,JSX语法--hello world

      前  言 毫无疑问,react是目前最最热门的框架(没有之一),了解并学习使用React,可以说是现在每个前端工程师都需要的. 在前端领域,一个框架为何会如此之火爆,无外乎两个原因:性能优秀,开发 ...

  6. 【原创】React实例入门教程(1)基础API,JSX语法--hello world

    前  言 毫无疑问,react是目前最最热门的框架(没有之一),了解并学习使用React,可以说是现在每个前端工程师都需要的. 在前端领域,一个框架为何会如此之火爆,无外乎两个原因:性能优秀,开发效率 ...

  7. 前端框架React Js入门教程【精】

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...

  8. React快速入门教程

    简介 Facebook官网介绍:React 是一个用来构建用户界面的 JavaScript 库.相当于 MVC 架构的 V 层. React 的核心思想是:封装组件,各个组件维护自己的状态和UI,当状 ...

  9. React JS快速入门教程

    翻译至官方文档<Tutorial>http://facebook.github.io/react/docs/tutorial.html 转载请注明出处:http://blog.csdn.n ...

随机推荐

  1. JavaScript 数组

    JavaScript 数组 简介:数组是值的有序集合,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改. 一:创建数组 ...

  2. STM32之DMA+ADC

    借用小甲鱼的经典:各位互联网的广大网友们.大家早上中午晚上好..(打下小广告,因为小甲鱼的视频真的很不错).每次看小甲鱼的视频自学都是比较轻松愉快的..我在想,如果小甲鱼出STM32的视频,我会一集不 ...

  3. 解决 adb.exe 停止工作小续

    继adb 停止工作的问题之后,又碰见了adb 停止工作的问题. 在使用adb install app.apk 之后给出错误信息如下: * daemon not running. starting it ...

  4. Python之路【第四篇】python基础 之基本数据类型之集合

    基本数据类型之集合 set set集合,是一个无序且不重复的元素集合 # set 不允许重复的集合 set允许重复的列表但是集合是无序的 #例如 # s = {1,23,23,4,55,55} # p ...

  5. java-JDBC配置驱动程序

    我们以常用的3种数据库为例. MySQL数据库 驱动程序包名:mysql-connector-java-3.1.11-bin.jar 驱动类的名字:com.mysql.jdbc.Driver JDBC ...

  6. BOM

    一.window对象1.全局作用域全局变量不能通过delete操作删除,而直接在window对象上定义的属性可以 var a = 1; delete a; console.log(a); window ...

  7. Struct2 csv文件上传读取中文内容乱码

    网络上搜索下,发现都不适合 最终改写代码: FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br= n ...

  8. HOJ 1797 Red and Black

    传送门  http://acm.hit.edu.cn/hoj/problem/view?id=1797 总体的思路是遍历可以到达的' . ',将其对应的vis数组化为1,然后统计所有为1的vis项; ...

  9. Centos 6.5 部署 redmine 3.3

    验证ruby版本 如果有就卸载安装最新的 yum install gcc* openssl openssl-devel -y wget https://ruby.taobao.org/mirrors/ ...

  10. C# RabbitMq .net 使用

    本文转载来自 [http://www.cnblogs.com/yangecnu/p/Introduce-RabbitMQ.html]写的很详细. 文件安装包官方DEMO下载地址是:http://pan ...