## 第六步:Flux架构速成教程 Flux是Facebook为可扩展的客户端web应用开发的应用架构。它利用单向数据流补全了React组件的一些不足。Flux更应该看做一种模式而非框架,不过,这里我们将使用一个叫做Alt的Flux实现,来减少我们写脚手架代码的时间。 以前你看过这个图解吗?你能理解它吗?我就不能理解,无论我看它多少遍。 ![](https://box.kancloud.cn/2015-09-14_55f642be3e089.jpg) 现在我对Flux比较了解了,我只能说,真是服了他们(Flux作者),能将简单的架构用如此复杂的方式展现出来。不过需要说明的是,它们的[新Flux图解](http://idlelife.org/archives/%22https://facebook.github.io/flux/docs/overview.html#structure-and-)比以前好多了。 > 有趣事实:当我刚开始写这个教程时,我决定不在这个项目中使用Flux。我实在掌握不了这个东西,还是让别人去教它吧。不过谢天谢地,在Yahoo我能在上班时间把玩不同的技术并试验它们,所以花点功夫还是学会了。老实说,不用Flux我们也能构建这个app,并且写的代码还少些,因为这个项目并没有什么复杂的内嵌组件。但我相信,做一个全栈的React app,包括服务端渲染和Flux架构,看着不同的部分是如何组合到一起的,这本身有它的价值。 与其重复Flux那抽象的[官方教程](https://facebook.github.io/flux/docs/overview.html),不如让我们来看一个真实的用例,来展示Flux是如何工作的: ![](https://box.kancloud.cn/2015-09-14_55f642bec00d0.jpg) * 在`componentDidMount`中,三个action被触发: ~~~ OverviewActions.getSummary(); OverviewActions.getApps(); OverviewActions.getCompanies(); ~~~ * 每一个action都创建了一个AJAX请求向服务器获取数据。 * 获取到数据后,每一个action触发另一个“success”的action,并且将数据传递给它: ~~~ getSummary() { request .get('/api/overview/summary') .end((err, res) => { this.actions.getSummarySuccess(res.body); }); } ~~~ * 同时,Overview的store(我们存储Overview组件状态的地方)监听所有“success”的action。当`getSummarySuccess`被触发后,Overview的store中的`onGetSummarySuccess`方法被调用,store被更新: ~~~ class OverviewStore { constructor() { this.bindActions(OverviewActions); this.summary = {}; this.apps = []; this.companies = []; } onGetSummarySuccess(data) { this.summary = data; } onGetAppsSuccess(data) { this.apps = data; } onGetCompaniesSuccess(data) { this.companies = data; } } ~~~ * 一旦store更新,Overview组件将会知道,因为它订阅了Overview store,当store更新/改变后,组件将会安装store中的值更新自身状态。 ~~~ class Overview extends React.Component { constructor(props) { super(props); this.state = OverviewStore.getState(); this.onChange = this.onChange.bind(this); } componentDidMount() { OverviewStore.listen(this.onChange); } onChange() { this.setState(OverviewStore.getState()) } ... } ~~~ * 此时Overview组件已经根据新数据更新完成了。 * 在上面的截图上,当从下拉菜单选择不同的日期范围,将会重复整个流程。 > 注意:Action如何命名并无规定,你可自由按照自己的习惯命名,只要它是描述性并且有意义的。 让我们暂时先忽略*Dispatcher*一会,从上面的描述你看到了一条单向的数据流吗?如果没有也没什么大不了的,当我们开始构建应用的时候你自然就明白了。 ![](https://box.kancloud.cn/2015-09-14_55f642bf3e417.jpg) ### Flux概要 Flux事实上不过是pub/sub架构的一个时髦说法,比如,应用的数据总是单向的,并被一路上的订阅者们接收。 在写这篇教程的时候,外面已经有超过一打的Flux实现,在这些实现当中,我只用过[RefluxJS](https://github.com/spoike/refluxjs)和[Alt](http://alt.js.org/),在这两者之间,我个人比较喜欢Alt,因为它的简洁,以及作者[goatslacker](https://github.com/goatslacker)的热心、支持服务端渲染、非常棒的文档,以及积极的维护。 我强烈建议你去读一下Alt的[Getting Started](http://alt.js.org/guide/),不超过10分钟你就能基本入门了。 如果你对于该选择哪个Flux库感到迷茫,可以考虑一下Hacker News上一个叫glenjamin的家伙的[评论](https://news.ycombinator.com/item?id=9833099),他花了大量时间试图弄清到底该用哪个Flux库: > 令人郁闷的事实是:它们(Flux库)都很好。你几乎不可能因为一个Flux库而让你的应用出现问题。即使某个Flux库停止维护了也不打紧,你要知道,大多数正常的Flux实现都非常小(大约100行代码),出不了什么致命问题,即使出了我想你也能搞定。总之,redux很灵巧,但不要在试图获得完美的Flux库上浪费时间,瞅着哪个还算顺眼就拿来用,赶紧将关注点转回到你的应用上去。 现在,我们已经过了一遍ES6、React、Flux的一些基础,现在该将注意力集中到我们的应用上来了。