## 第六步:Flux架構速成教程
Flux是Facebook為可擴展的客戶端web應用開發的應用架構。它利用單向數據流補全了React組件的一些不足。Flux更應該看做一種模式而非框架,不過,這里我們將使用一個叫做Alt的Flux實現,來減少我們寫腳手架代碼的時間。
以前你看過這個圖解嗎?你能理解它嗎?我就不能理解,無論我看它多少遍。

現在我對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是如何工作的:

* 在`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*一會,從上面的描述你看到了一條單向的數據流嗎?如果沒有也沒什么大不了的,當我們開始構建應用的時候你自然就明白了。

### 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的一些基礎,現在該將注意力集中到我們的應用上來了。
- 前言
- 概述
- 第一步:新建Express項目
- 第二步:構建系統
- 第三步:項目結構
- 第四步: ES6速成教程
- 第五步: React速成教程
- 第六步:Flux架構速成教程
- 第七步:React路由(客戶端)
- 第八步:React路由(服務端)
- 第九步:Footer和Navbar組件
- 第十步:Socke.IO – 實時用戶數
- 第十一步:添加Character的組件
- 第十二步:數據庫模式
- 第十三步:Express API 路由(1/2)
- 第十五步:Home組件
- 第十四步:Express API 路由(2/2)
- 第十六步:角色(資料)組件
- 第十七步:Top 100 組件
- 第十八步:Stats組件
- 第十九步:部署
- 第二十步: 附加資源
- 總結