React之Flux

Flux是Facebook用来构建客户端Web应用的应用架构。它利用单向数据流的方式来组合React中的视图组件。它更像一个模式而不是一个正式的框架,开发者不需要太多的新代码就可以快速的上手Flux。

工作流程

1、用户访问 View
2、View 发出用户的 Action
3、Dispatcher 收到 Action,要求 Store 进行相应的更新
4、Store 更新后,发出一个"change"事件
5、View 收到"change"事件后,更新页面
在这里插入图片描述

四个组成部分

View: 视图层
Action(动作):视图层发出的消息(比如click) 调用 dispatch方法发数据
Dispatcher(派发器):用来接收Actions、执行回调函数-register 方法接收
Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面

dispatcher与action

dispatcher是事件调度中心,flux模型的中心枢纽,管理着Flux应用中的所有数据流。它本质上是Store的回调注册。每个Store注册它自己并提供一个回调函数。当Dispatcher响应Action时,通过已注册的回调函数,将Action提供的数据负载发送给应用中的所有Store。应用层级单例

Store

Store负责封装应用的业务逻辑跟数据的交互。
Store中包含应用所有的数据
Store是应用中唯一的数据发生变更的地方
Store中没有赋值接口—所有数据变更都是由dispatcher发送到store,新的数据随着Store触发的change事件传回view。Store对外只暴露getter,不允许提供setter!!禁止在任何地方直接操作Store。

controller-view

controller-view 可以理解成MVC模型中的controller,它一般由应用的顶层容器充当,负责从store中获取数据并将数据传递到子组件中。简单的应用一般只有一个controller-view,复杂应用中也可以有多个。controller-view是应用中唯一可以操作state的地方(setState())

view

view(UI组件) ui-component 职责单一只允许调用action触发事件,数据从由上层容器通过属性传递过来。

actionCreator

actionCreators是相对独立的,它作为语法上的辅助函数以action的形式使得dispatcher传递数据更为便利。

flux核心api

Action为对象方法 接收view的响应
方法内部响应dispatcher对象的dispatch方法
Dispatch对象 由 flux对象引入Dispatcher对象 创建 Dispatch对象 new Dispatcher()
响应action的dispatch 方法 在dispatch对象中使用 register注册回调接收数据
Dispatch.register((action)=>{}) action参数为Action对象方法提供的数据
判断符合条件 调用store的相应处理方法以及change事件
Store中change事件的触发通过this.emit 监听改变通过 this.on() 使用的是events模块中EventEmitter对象
拷贝属性方法使用 object-assign 原生js依赖中的 assign对象
顶层容器中调用store的获取数据 以及在dom加载完成函数中调用store监听

步骤

创建一个react脚手架
创建一个文件夹fls,小技巧创建五个组成部分,5个文件,Actions.js、Demo.js、Dispatch.js、Store.js、TodoController.js
在这里插入图片描述
Store 添加 发送, 监听 获取所有数据

Action.js

//active----动作层

var Action ={
    addTodos(text){
        return{
            actionType:"ADD_TODO",
            text:text       
        }
    },
    rmTodos(text){
        return{
            actionType:'RM_TODO',
            text:text
        }
    }
}

export default Action;

Demo.js

//view---用来进行数据展示
import React from "react";
class Demo extends React.Component{
    add(){
        this.props.name(this.refs.ipt.value)
        this.refs.ipt.value=""    //点击add把输入框里面的值传给顶层容器,并清空输入框
    }
    del(i){
        this.props.remove(i)   //点击删除删除这一个
    }
    render(){
        var _this = this;
        return(
            <div>
                <h1>TodeList</h1>
                <input type="tezt" ref="ipt"/>
                <button onClick={_this.add.bind(this)}>点击</button>
                {
                    this.props.list.map(function(item,i){
                        return(
                            <div key={i}>{item}---<button onClick={_this.del.bind(_this,i)}>删除</button></div>
                        )
                    })
                }
            </div>
        )
    }
}

export default Demo;

Dispatch.js

//派发器---事件调度中心----接受action    命令store修改

import {Dispatcher} from "flux";
import Store from "./Store";
//实例化派发器对象

var Dispatch = new Dispatcher()

Dispatch.register((action)=>{
    //判断一下action的类型
    switch (action.actionType) {
        case "ADD_TODO":
            //命令store添加数据---action.text---store-change       
            Store.addtodoitem(action.text) //添加数据
            Store.changes()                  //发出change事件
            break;
        case "RM_TODO":
            Store.removeTodoItem(action.text)
            Store.changes()
            break;
    }
})

export default Dispatch;

Store.js

//仓库--发出change事件

//Store==存储数据,执行修改数据的业务逻辑,发出change(emit)
import {EventEmitter} from "events";
//拷贝对象
import assign from "object-assign";
var Store=assign({},EventEmitter.prototype,{
    Todos:[],  //存储所有的数据
    addtodoitem(text){   //添加数据
        this.Todos.push(text)  
    },
    removeTodoItem(text){
        this.Todos.splice(text,1)
    },
    changes(){//修改成功后发出change事件,类似于监听
        this.emit("change")
    },
    changelisten(callback){
        this.on('change',callback)
    },
    getAll(){
        return this.Todos   //讲store里面的所有数据通过这个函数返回过来
    }
})
export default Store

TodoController.js

import React from "react";
import Demo from "./Demo"
import Action from "./Action"; 
import Dispatch from './Dispatch';
import Store from './Store';
class TodoController extends React.Component{
    constructor(props){
        super(props)
        this.state={
            list:Store.getAll()
        }
        this.changeitem = this.changeitem.bind(this)
    }

    addTodo(text){
        // text==视图容器里面的数据
        Dispatch.dispatch(Action.addTodos(text))    //派发器通过dispatch方法来接受actions里面的add方法
    }
    removeTodo(i){
        Dispatch.dispatch(Action.rmTodos(i))
    }
    changeitem(){  //调用setState的方法
        this.setState({list:Store.getAll()})
    }
    componentDidMount(){
        Store.changelisten(this.changeitem)
    }

    render(){
        return(
            <div>
                <h1>顶层容器</h1>
                <Demo name={this.addTodo} list={this.state.list} remove={this.removeTodo}/>
            </div>
        )
    }
}

export default TodoController;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值