详解react flux架构工作方式 -pg电子游戏网站

0顶
0踩

详解react flux架构工作方式

2015-09-01 15:26 by 副主编 mengyidan1988 评论(0) 有6406人浏览
【编者按】作者在《 》一文中 讨论facebook的flux架构的工作方式,以及开发者应该如何在项目中使用它。为了让前端开发者更好地掌握本文内容,对该文章进行了翻译,内容如下:

什么是flux

flux是facebook内部用来构建react应用的一套架构。它本身并不是一个框架或库。它仅仅是一个用于完善react应用开发的一种新的应用程序架构,flux架构最大的特点是其倡导的单向数据流方案。

facebook还提供了dispatcher的开源库。你可以将dispatcher认为是一种全局pub/sub系统的事件处理器,用于向所注册的回调函数广播payloads。通常情况下,如果你使用flux架构,你可以借助于facebook提供的这个dispatcher实现,并且可以借助nodejs中的eventemitter模块来配置事件系统, 从而帮助管理应用程序的状态。

组成结构

flux主要包括下面四个独立的组件,下面简单地解释下:
  • actions:帮助向dispatcher传递数据的辅助方法;
  • dispatcher:接收action,并且向注册的回调函数广播payloads;
  • stores:应用程序状态的容器&并且含有注册到dispatcher的回调函数;
  • controller views:react组件,从store获取状态,并将其逐级向下传递给子组件。

让我们通过一幅图来简单看一下这四个部分的关系:



如何处理外部api

但是,很多场景下不仅仅包括应用程序内部的状态数据,还可能包括来自外部的数据,也就是如果我们需要消费restful服务,那么我们该如何将这些外部数据引入到flux架构的单向数据流中呢?经过实践,我们发现,在action中引入外部数据流是个不错的实践, 数据然后再被送到store中。

在继续阅读之前,我强烈建议你阅读下facebook提供的flux官方示例程序的 源代码。在你简单阅读了这个例子的源代码后,我们再来详细的探讨flux中这几个组件的作用:

dispatcher

我们首先来看看dispatcher的作用:你可以将dispatcher看成是flux架构中整个数据流程的管理者。或者你可以将它看成你整个应用的中央交换机。dispatcher接收actions作为payloads,并且将payloads分发给所注册的回调函数。

那么它就是一个pub/sub吗?

不完全是。dispatcher会将payload广播给所有向它注册的回调函数,并且包括了允许你以指定次序调用这些回掉函数的执行逻辑,例如在处理前等待数据更新。在flux架构中只有一个dispatcher,它是你整个应用的中央hub。我们来创建一个简单的dispatcher:
var dispatcher = require('flux').dispatcher;
var appdispatcher = new dispatcher();
appdispatcher.handleviewaction = function(action) {
  this.dispatch({
    source: 'view_action',
    action: action
  });
}
module.exports = appdispatcher;

在上面的代码中,我们创建了一个dispatcher的实例,它包括了一个叫做handleviewaction的方法。创建这个方法的目的是为了让你能够轻松的区分, 是视图层触发的action,还是服务器/api触发的action。

在handleviewaction方法中调用了dispatch方法(该方法来自dispatcher实现),它会将payloads广播给所有注册到它的回调函数 (注意,这里所说的回调是在store中注册给dispatcher的)。然后,action会触发store中相应事件,并最终体现在state的更新上。

可以用下面这张图来表示这个过程:



依赖

facebook所提供的dispatcher模块还有一个非常赞的功能,那就是它能够定义依赖,并在store中向dispatcher注册回调函数。 因此,如果你的应用的某个部分依赖于其他部分的数据更新,为了能够进行合适的渲染,dispatcher中的waitfor方法将会非常有用。

为了能够利用这一特性,我们需要在store中存储注册给dispatcher的回调函数的返回值,这里,我们命名为dispatcherindex:
shoestore.dispatcherindex = appdispatcher.register(function(payload) {
});

然后在store中处理每一个被分发的action时,我们可以使用dispatcher的waitfor方法来确保我们的shoestore已经被更新了,示例代码如下:
case 'buy_shoes':
  appdispatcher.waitfor([
    shoestore.dispatcherindex
  ], function() {
    checkoutstore.purchaseshoes(shoestore.getselectedshoes());
  });
  break;

stores

在flux中,可以用store来分领域的管理应用程序的状态,例如shoestore、appstore等。从一个更高层角度来看,可以简单地认为应用的每一个部分可以对应于一个store,store可以用来管理数据,定义数据检索方法,此外,store中还包括了注册给dispatcher的回调函数。

下面我们来看一个简单的store的例子:
var appdispatcher = require('../dispatcher/appdispatcher');
var shoeconstants = require('../constants/shoeconstants');
var eventemitter = require('events').eventemitter;
var merge = require('react/lib/merge');
// internal object of shoes
var _shoes = {};
// method to load shoes from action data
function loadshoes(data) {
  _shoes = data.shoes;
}
// merge our store with node's event emitter
var shoestore = merge(eventemitter.prototype, {
  // returns all shoes
  getshoes: function() {
    return _shoes;
  },
  emitchange: function() {
    this.emit('change');
  },
  addchangelistener: function(callback) {
    this.on('change', callback);
  },
  removechangelistener: function(callback) {
    this.removelistener('change', callback);
  }
});
// register dispatcher callback
appdispatcher.register(function(payload) {
  var action = payload.action;
  var text;
  // define what to do for certain actions
  switch(action.actiontype) {
    case shoeconstants.load_shoes:
      // call internal method based upon dispatched action
      loadshoes(action.data);
      break;
    default:
      return true;
  }
  
  // if action was acted upon, emit change event
  shoestore.emitchange();
  return true;
});
module.exports = shoestore;

以上代码可能做的最重要的一件事就是:我们使用nodejs中的eventemitter模块来扩展我们的store。这使得我们的store能够监听和广播事件。这也使得我们的视图/组件能够基于这些事件来更新。 这是因为我们的控制器视图(controller view)会监听我们的store, 并利用这一点通过发出事件方式通知控制器视图应用程序的状态发生了改变, 从而进行视图层的重新渲染。

在store中还有一个值得注意的事,那就是我们使用dispatcher的regiter方法来注册回调函数。 这意味着,我们创建的store会监听来自appdispatcher的广播,这里我们使用switch语句来 区分广播内容所对应的action。如果一个相关的action发生了,那么就触发一个change事件,并且监听 此事件的视图会根据新的状态(state)进行重新渲染。这个过程如下图所示。



在上面的代码中,shoestore中还包括一个公共方法getshoes(),它可以在控制器视图中被调用, 用于检索所有在_shoes对象中的数据,并且使用这个数据作为组件的状态数据。因为这是个非常简单 的例子,在实际应用开发中你可以使用更加复杂的数据处理逻辑。

action创建器和actions

行为创建器(action creators)是一组会在视图中被调用的方法(也可以在其他地方使用), 它们用于向dispatcher发送actions。也就是说,我们使用dispatcher分发的payloads,实际上就是actions。

在facebook提供的例子中,action的类型常数被用于定义这些action所被应用的场景,并且是伴随着action一起被传递的。现在,在所注册的回调函数内部,这些actions可以根据他们的action类型来处理。

我们可以看一个简单的类型常数的定义:
var keymirror = require('react/lib/keymirror');
module.exports = keymirror({
  load_shoes: null
});

在上面的代码中,我们用了react的keymirror库来生成我们的类型常数的key/value对。如果仅仅是看这个文件,我们大致可以猜到我们的应用会加载鞋子(shoes)。借助于类型常数,可以使得应用 中涉及到的事物变得更加地可组织,可以让开发者能通过这样的高层抽象来组织应用程序。

现在,让我们来大致的看一个对应的行为创建器(action creator)的定义:
var appdispatcher = require('../dispatcher/appdispatcher');
var shoestoreconstants = require('../constants/shoestoreconstants');
var shoestoreactions = {
  loadshoes: function(data) {
    appdispatcher.handleaction({
      actiontype: shoestoreconstants.load_shoes,
      data: data
    })
  }
};
module.exports = shoestoreactions;

在上面的代码中,我们在定义了shoestoreactions对象,并在其中定义了loadshoes()方法, 该方法内调用了来自appdispatcher的handleviewaction方法,并且将相应的行为类型与 我们提供的数据相关联。现在,我们可以在我们的视图代码或api中引入这个action文件。我们可以调用shoestoreactions.loadshoes(ourdata)方法来向dispatcher发送payload,随后dispatcher会将它广播出去。shoestore则会监听来自dispatcher的广播,并且触发相应的事件来加载相应的鞋子。

控制器视图 controller view

你可以简单的将控制器视图理解为react组件,这些组件会监听change事件,如果事件发生了, 就从stores中获取应用程序新的状态数据。随后,可以将数据通过props逐级向子组件传递。这个过程大致如下图所示:



让我们来看看代码长啥样:
/** @jsx react.dom */
var react = require('react');
var shoesstore = require('../stores/shoestore');
// method to retrieve application state from store
function getappstate() {
  return {
    shoes: shoestore.getshoes()
  };
}
// create our component class
var shoestoreapp = react.createclass({
  // use getappstate method to set initial state
  getinitialstate: function() {
    return getappstate();
  },
  
  // listen for changes
  componentdidmount: function() {
    shoestore.addchangelistener(this._onchange);
  },
  // unbind change listener
  componentwillunmount: function() {
    shoesstore.removechangelistener(this._onchange);
  },
  render: function() {
    return (
      
    );
  },
  
  // update view state when change event is received
  _onchange: function() {
    this.setstate(getappstate());
  }
});
module.exports = shoestoreapp;

在上面的代码中,我们使用addchangelistener来监听change事件,并且在接收到事件后更新应用程序的状态数据。

我们的应用程序状态数据存储在store中,因此我们可以用store中的公共方法来获取数据,然后将其设置为应用程序的状态。

完整的数据流程

前面我们依次解读了flux架构中的每一个独立部分,我们有了对flux架构中的每一个组件的一个大致的认识, 并且能大致的了解了flux架构的工作流。在这之前,我们已经通过了几张图片描述了数据在组件之间的流向, 现在让我们将上面的子流程组合起来,以更好的理解flux的数据流:

小结

在读完这篇文章后,如果你之前并不了解facebook的flux架构,那么希望你现在能够说理解了。 但另一方面,如果不在react的实际编程开发中使用这一架构,你是很难真正的体会到flux架构的 特点的。

当你使用flux后,你会发现没有flux的react应用开发就相当于是没有jquery的dom遍历操作。也就是说, 没有flux你可以照常进行react应用开发,但是你在代码组织和数据流程上会缺乏优雅的pg电子游戏网站的解决方案。

另一个方面,如果你想使用flux架构,但你并不想使用react,那么你可以参考 delorean,它是一个flux框架,并且可以让你使用ractive.js或者flight。另一个值得参考的库是 fluxxor,它实现了在紧耦合的flux组件中包含一个中央flux实例。

最后,再次说明,如果要真正的理解flux,你就得在实际开发中体验它。

原文链接:

译者简介:景庄,前端工程师,关注node.js、前端工程化。个人博客: http://wwsun.github.com。
  • 大小: 3.2 kb
  • 大小: 2 kb
  • 大小: 4.1 kb
  • 大小: 3 kb
  • 大小: 112.6 kb
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • flux架构

  • flux 是一种架构思想,专门解决软件的结构问题。它跟mvc 架构是同一类东西,但是更加简单和清晰 二、基本概念 flux将一个应用分为四个部分 view: 视图层 action(动作):视图层发出的消息(比如mouseclick) ...

  • 一、什么是flux  flux 是一种架构思想,专门解决软件的结构问题。... 安装----建立完react项目之后在文件目录下cmd : cnpm i flux --dev 二、flux的基本概念  (1) 、flux由4部分组成  1、view:视图层  ...

  • 本文就对于当下主流的前端开发技术react、vue、angular这三个框架做个相对详尽的探究,目的是为了解开这些前端技术的面纱,看看各自的庐山真面目。 【react】 react(也被称为react.js或reactjs)是一个用于构建...

  • react react的重点 webpack webpack 是一个现代 javascript 应用程序的静态模块打包器(module bundler)。 当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每...

  • react 本身只涉及ui层,如果搭建大型应用,必须搭配一个前端框架。也就是说,你至少要学两样东西,才能基本满足需要:react 前端框架。 ...简单说,flux 是一种架构思想,专门解决软件的结...

  • pg电子游戏网站官网:https://projectreactor.io/ 教程:... reactor的类型 reactor有两种类型,flux<t>和mono<...flux类似raxjava的observable,它可以触发零到多个事件,并根据实际情况结束...

  • 然后就出现了这样的结果 导致混杂的数据流和不可预测的结果 flux 架构概述 在2013年,facebook 让 react 亮相时,对于当时世面上的 mvc 框架并不满意,于是就有了flux。并推出了 flux ,但 flux 并不是一个 mvc 框架...

  • 设计模式--flux架构(模式)1 简介2 flux介绍3 flux机制4 flux使用5 经典实现参考 1 简介 application architecture for building user interfaces. 用于构建用户界面的应用程序体系结构。 核心是单向数据流。 2 ...

  • 今天我们来结合一个简单的demo来讲解flux框架,让大家了解flux框架的真面目。 先上一张比较漂亮的图(对漂亮的图,总是没有抵抗力:-) )。 我们再来回顾下flux框架的四大组成部分 view: 视图层action...

  • 之前小编发过一篇类似的文章,前端面试vue 高频原理篇 详细解答,还有105道vue面试题集合,整合了vue面试题,这次整合了react面试题,两份面试题集合都可以点击这获取哦 为什么选择使用框架而不是原生? 框架的好处: ...

  • flux 是 facebook 开发,用来帮助 react 之类的应用做状态管理的模式,它利用单向数据流,来梳理复杂的状态 一个 flux 应用由三个部分组成 dispatcher 负责分发事件 store 负责保存数据,并且响应事件更新...

  • 本文就对于当下主流的前端开发技术react、vue、angular这三个框架做个相对详尽的探究,目的是为了解开这些前端技术的面纱,看看各自的庐山真面目。 【react】 react(也被称为react.js或reactjs)是一个用于构建...

  • flux 是 facebook 用于构建 web 客户端的一种应用架构。它利用单向数据流,来帮助复杂的 react 组合组件的状态管理。它是一种模式,而不仅仅是一个框架,你可以不需要写任何新代码来将 ...

  • 本教程打算以一种大家都能理解方式图解 flux。 问题 首先必须先说明一下 flux 到底解决什么问题。flux 是一种应用处理的数据的模式。虽然 flux 和 react 一同在 facebook 成长起来的,很多人把它们合到一起来...

  • 由ios原生开发转到react native开发,再接着慢慢开始学习前端开发,真心觉得搞技术太难了这句话太正确了。当前正在开发的项目中使用了vue vuex electron来实现桌面应用...vuex数据流架构学习笔记(一)-flux 是这次系...

  • react react的重点 webpack webpack 是一个现代 javascript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每...

  • react 之 redux 的使用方法介绍概念storereduceraction实现共享总结 ...flux 架构就像眼镜:您自会知道什么时候需要它。   其次,安装: // 作用:创建store的 cnpm install redux -s // 作用:把redux和

  • vb语言vb光盘管理系统设计(源代码 系统)本资源系百度网盘分享地址

  • h型脚架疲劳测试机sw16可编辑_零件图_机械工程图_机械三维3d建模图打包下载.zip

global site tag (gtag.js) - google analytics
网站地图