react-flux的使用(2018/12/16)

一、什么是Flux
  Flux 是一种架构思想,专门解决软件的结构问题。它跟MVC 架构是同一类东西,但是更加简单和清晰。
        解决非父子组件传值,数据共享
        安装----建立完react项目之后在文件目录下cmd :  cnpm i  flux --dev
二、flux的基本概念
  (1) 、Flux由4部分组成
  1、View:视图层
  2、Action(动作):视图发出的消息(比如mouseClick),不是VUE中异步的方法
  3、Dispatcher( 派发器 ) :用来接收Action、执行回调函数
  4、Store(数据层):用来存放应用的状态,一旦发生改动,就提醒View更新页面

 

      (2)、Flux的流程
  1、用户访问View

 

  2、View发送用户的Action
  3、Dispatcher收到Action,要求Store进行相对应的更新
  4、Store更新后,发出一个“onchange”事件
  5、view接受到“onchange”事件后,更新页面
在涉及到数据的公共状态管理时不能直接修改state中的数据,因为数据是单向传递的
 
console.log(dispatcher)
App.js
 
import React, { Component } from 'react';
import store from './store'
import dispatcher from "./store/dispatcher"
console.log(dispatcher)
class App extends Component {
    constructor(){
      super();
      this.state=store.getState()  //从getState中获取数据
      console.log(this.state)
      store.handleUpdate(this.handleUpdate.bind(this))  //第八步 这里的()中的数就是要传递的新的参数,store.handleUpdate来接受这个参数
    }
  render() {
     let {n} = this.state
    return (
      <div>
        <h2>{n}</h2>
        <button onClick={this.handleAdd.bind(this)}>增加</button>  {/*第一步 在视图中点击按钮 触发一个action*/}
      </div>
    );
  }
  handleAdd(){  
      let action = {
        type:"ADD_NUMBER" //这是对action动作的一个描述
      }
      dispatcher.dispatch(action)  //第二步 给action设定类型,然后传递给dispatcher
  }
  handleUpdate(){  //第七步 写一个函数来修改this.state中的数据,这时的getState()中的数据已经是更新过后的了
    this.setState(store.getState())  //这是更新了this.state中的数据,this.state发生改变,render执行,页面被重新渲染
  }
}
 
export default App;
 
 
 
dispatcher.js
import {Dispatcher} from "flux"  //flux中有一个dispatcher方法  这一步要安装flux   cnpm i flux --dev
import store from './index'
const dispatcher = new Dispatcher()   //创建一个dispatcher ,它身上会有许多方法
 
dispatcher.register((action)=>{  //dispatcher.register用于接收App.js中由dispatcher.dispatch传过来的action,做业务逻辑处理
    switch(action.type){  //第三步 dispatcher判定对应的action类型来调用store中对应的函数
        case "ADD_NUMBER":store.handleAddNum();
    }
})
export default dispatcher
index.js
const EventEmitter=require("events");  //引入node时间模块,利用事件模块中的on emit方法
 
const store = Object.assign(EventEmitter.prototype,{   //合并对象   将事件模块的方法和数据进行合并生成一个新的对象
    //将来自一个或多个源对象中的值复制到一个目标对象   Object.assign(target,source)
    state:{ //公共的状态,将所有公共的数据放在state中
            n:0
    },
    getState(){ //获取state对象,哪个组件需要调用数据就调用这个方法,使其数据公共化
            return this.state
    },
    handleAddNum() //第四步 store执行相应的函数   ,当handleAddNum被dispatcher调用的时候,emit触发update事件
        this.state.n++;
        console.log(this.state.n)
        this.emit("update")  //触发事件用于让页面发生改变
    },
    handleUpdate(cb){   //第五步  当update函数被emit触发后写一个函数来绑定update事件并且执行这个函数,并设定一个回调函数来接受数据的变化
            this.on("update",cb)
    }
})
 
export default store;
 
 
三、store代码流程
 
 
四、组件中调用Store
import Store from "./store";
 
class App extends Component{
constructor(props){
super(props);
//调用公共数据
this.state = Store.getState();
}
 
五、创建Dispatcher.js
 
安装flux:cnpm install flux --save-dev
 
(1)在View层的方法中创建Action并传递给dispatcher  方法: dispatcher.dispatch(Action)
 
(2)判断类型Action的type是否相等,如果相等则调用Store的方法进行修改数据(注意:修改数据的方法只能在Store中使用,这样的方式很类似于后端的MVC模式)
 
六、监听数据变化
数据发生改变View层页面进行更新
 
(1)在Store中有提供数据改变的函数,在数据改变的函数中调用事件触发this.emit("事件名称")
 
(2)同时在Store中在创建一个函数,函数内部进行事件监听this.on("事件名称",fn)供View层调用,当事件触发时会调用这个函数,然后我们this.setState进行数据的改变
 
Store中的事件监听和触发
 
组件中调用事件监听的方法用于改变数据
 
如果还想细化代码结构我们还可以将Action分离出去(尝试一下)
在项目中Store和dispatcher可以有多个,非常灵活
除此之外我们的View层既有view层又有controller层所以我们还可以进行再次拆分
posted @ 2019-09-12 11:01  zsrTaki  阅读(416)  评论(0编辑  收藏  举报