数据流架构学习笔记(一)-Flux

由iOS原生开发转到React Native开发,再接着慢慢开始学习前端开发,真心以为搞技术太难了这句话太正确了。当前正在开发的项目中使用了Vue+Vuex+Electron来实现桌面应用开发,在学习了Vuex以后,决定对以前学的各类数据流管理架构作一个系统的总结,因此接下来我还会总结
数据流架构学习笔记(二)-Redux
数据流架构学习笔记(三)-Vuex
数据流架构学习笔记(一)-Flux 是此次系统总结的第一篇笔记,都是一些本身的学习和总结,权当学习参考。javascript

Flux是什么?

Flux是Facebook官方提出一种架构思想,他的出现一样也是为了解决实际项目中软件结构的问题,若是你了解过MVC,MVVM之类的东西,其实就应该知道这是同样的东西,他们是一种思想,为了让你的应用可以更加合理的工做和运行,具体到如何应用在你的项目中,经过代码和一些工具能够仁者见仁、智者见智的使用。html

Flux如何工做

一个 Flux 应用主要包含四个部分:前端

  • the dispatcher: 处理动做分发,而且向注册的回调函数广播payloads,维护 Store 之间的依赖关系
  • the stores: 应用程序状态的容器,而且含有注册到Dispatcher的回调函数,数据和逻辑部分
  • the views: 视图组件,这一层能够看做controller-views,做为视图同时响应用户交互
  • the actions: 提供经过具体行为使用dispatcher 传递数据给 store,是一些使用Dispatcher传递数据的具体方法集合

Flux 的核心单向数据流是这样运做的:java

View -> Action -> Dispatcher -> Store -> View复制代码

更多时候 View 会经过用户交互触发 Action,因此一个简单完整的数据流相似这样:react

假设如今在项目中,Action模块、Stroe模块、View模块等都已创建成功,Dispatcher来自官方Flux库,以从页面登陆的例子进行一次Flux流程说明,流程以下:bash

  1. 页面点击登陆按钮,View触发点击动做,调用Action中的网络请求封装函数;
  2. Action调用网络库相关API,并成功返回用户登陆成功参数,或返回失败错误。
  3. 在成功返回的callback中经过Dispatcher分发用户信息Payload至Store更改数据并存储新数据中。
  4. store经过前期已注册的对应通知及emit()将最新的数据分发出去,页面监听到数据变化,从而更新页面数据,从新渲染页面。

实例应用

由于工做偏向React Native,这里以登陆流程中部分React Native代码展现如何将Flux应用到React Native开发中进行数据管理,(因为代码时间较久,存在一些不合理之处请忽略,但不影响Flux数据流的理解):网络

视图层View:

登陆页:架构

...
_login(userName, passWord) {
        LoginActions.login({
            username: userName,
            password: passWord,
            ...
        }, (response) => {
            this.props.navigator.resetTo({comp:MainContainer});
        }, (error) => {
            Alert.alert(
                '提示',
                'error',
                [{ text: '肯定' }]
            );
        });
    }
...复制代码

主页:app

class Main extends Component{
    constructor(props){
        super(props);
        this.state = {
            user: AppStore.getUser(),
            ...
        };
    }
    componentDidMount() {
       AppStore.addChangeListener(this._userStateChange, 'USER_CHANGE');
    }
    componentWillUnmount() {
       AppStore.removeChangeListener(this._userStateChange, 'USER_CHANGE');
    }
    _onChange: function () {
        this.setState({
            user: AppStore.getUser()
        });
    },
    ...
    ...
}复制代码

登陆页是你的点击交互事件,你经过点击触发登陆调用Action,主页Main会存在登陆后返回的用户信息,数据来源于你的数据仓库AppStore,页面固然还存在页面监听者,知道当你的数据改变的时候,知道该如何去更新你的页面。函数

行为Action:

...
const _login = (params, callback, failure) => {
    const requestUrl = CommonLink.login(params.username, params.password);
   return Fetcher.getFetch(requestUrl)
       .then((response) => {
           AppDispatcher.dispatch({
               actionType: AppConstants.LOGIN,
               data: response.body,
           });
           callback(response);
       }).catch((error) => {
           failure(error);
       });
};
...
module.exports = {
    login: (params, callback, failure) => _login(params, callback, failure),
    ...
}复制代码

触发一个行为调用Action方法进行了网络API的调用,进行登陆,并返回成功用户信息后,经过Dispatcher将数据和消息分发出去,把接下来的工做交给数据仓库Store。

数据仓库Stores:

const dataStore = {
    user: {},
    ...
}

const AppStore = _.assign({}, EventEmitter.prototype, EventEmitter.prototype._maxListeners = 30, {
  emitChange(event = 'DEFAULT_EVENT') {
    this.emit(event);
  },

  addChangeListener(callback, event = 'DEFAULT_EVENT') {
    this.on(event, callback);
  },

  removeChangeListener(callback, event = 'DEFAULT_EVENT') {
    this.removeListener(event, callback);
  },
  ...
  getUser: () => dataStore.user || {},
  ...
});

...

// Register callback to handle all updates
AppDispatcher.register((action) => {
  switch (action.actionType) {
    ...
    case AppConstants.LOGIN:
      _.assign(dataStore, {
        username: action.data.user.username,
        ...
      });
      AppStore.emitChange('USER_CHANGE');
      break;
    ...
  }
});

module.exports = AppStore;复制代码

在数据仓库中,你应该定义出仓库对象AppStore,并对AppDispatcher注册入各类操做,即当接收到AppDispatcher发来的不一样消息时,操做数据并保存数据到dataStore中,以后经过AppStore.emit()将更新通知发送到页面中,让页面进行从新渲染。从而完成整个Flux数据流的闭环。

关于AppDispatcher和AppConstants

上述代码中用到的AppDispatcher和AppConstants代码以下:
AppDispatcher:

import {Dispatcher} from 'flux'
module.exports = new Dispatcher();复制代码

AppConstants:

const keyMirror = require('keymirror');

const AppConstants = keyMirror({
  ...
  LOGIN: null,
  ...
});
module.exports = AppConstants;复制代码

能够看出这些只是为了更好的使用Flux而引入库和辅助工具,你也可使用其余相似工具。

总结

Flux学习和理解须要的是在项目中实际应用进去,一样只要理解了单向数据流的思想,理解Flux也是很快的,Flux是单向数据流的一种具体架构实现。接下来会再总结关于Redux的理解和使用,一样也是单向数据流的一种具体实现,基于Flux,可是比Flux更加方便和强大。而当前的不少React开发项目也都基于使用Redux。

虽然搞技术很难,可是作本身喜欢的事情仍是很开心的,一块儿学习,努力奋斗。

参考博客:

Flux 架构入门教程-阮一峰
详解React Flux架构工做方式

相关文章
相关标签/搜索