Flux 是 Facebook 定義的一種單向數據流架構,設計思想以下,單向數據流是flux的核心 react
(flux就像水流一旦流出不能回頭,有別於angularJs的雙向綁定) 編程
Flux 避免使用 MVC 有利於單向數據流。當用戶和react-views交互時,view會經過一箇中央Dispatcher傳播一個動做 服務器
給保持程序數據安定業務邏輯的各個store,更有全部受影響的視圖,它容許store發送不指定在state間如何轉換視圖。 架構
咱們開始着手正確處理獲取的數據,好比,咱們想要展現消息線程未讀數,而另外一個視圖顯示一個未讀消息高亮顯示的 編輯器
線程列表,這個用MVC是難於控制的----標記單獨一個線程是已讀將會更新線程model,也須要更新未讀數model,這些依賴項 ide
和級聯更新一般發生大型MVC應用程序中,這將會致使數據流交織和不可預測的結果。 函數
Control 和 store 反轉:stores接受更新並根據須要對他們進行協調,而不是依賴外部的一些一致的方法來更新數據 spa
Store之外的任何事物,都不會知道洞察store裏面是如何管理內部數據的,有助於保持對關注點的明確分離,Store沒有直接setter 線程
方法,而是隻有一種方法獲取數據導入到本身內部—在dispatcher中註冊的回掉 設計
結構和數據流
數據在Flux架構的程序中式單向流動的。
單向數據流式Flux模式的核心,上圖式Flux程序的基本意圖模型,Dispatcher,stores,Views是有着輸入和輸出區分獨立的節點。
Action是包含新數據和一個標識屬性的簡單對象。Views會引起新的action做爲用戶交互響應在系統中傳播。
全部的數據流都會經過Dispatcher中心樞紐,Actions在一個action 製造方法中被提供給Dispatcher,最多見的來源是用戶與
視圖交互,而後Dispatcher調用store註冊的回掉函數分發action給store。在其註冊的回掉函數中,store對與所維護的狀態
相關的任何actions都做出響應。Store會發送一個更變事件去提醒controller-view數據層發生了變化。Controller-view層監聽這些事件
而且獲取數據而後調用本身的setstate方法,從新繪製頁面。
這種結構使咱們可以很容易地對咱們的應用程序進行推理, 這種方式可讓人聯想到功能性的反應性編程, 或者更具體地說是數據流編
程或基於流的編程, 其中數據經過一個單一的方向流向應用程序--沒有雙向綁定。應用程序狀態僅在stores中維護, 從而使應用程序的
不一樣部分保持高度的解耦。在stores之間發生依賴關係時, 它們保持在嚴格的層次結構中, 同步更新由Dispatcher程序管理。
咱們發現雙向數據綁定致使了級聯更新, 在這種狀況下, 更改一個對象致使另外一個對象發生更改, 這也可能觸發更多更新。隨着應用程序的增加,
這些級聯更新使得很難預測因爲一個用戶交互的結果會發生什麼變化。當更新只能在單個回合中更改數據時, 整個系統就變得更加可預測。
單個Dispatcher
Dispatcher是在flux程序中管理數據流的中心樞紐,它基本上是一個回掉函數到store的註冊表,本身沒有真正意識。它是分發action給store的一個
簡單裝置,任何一個store都會註冊它本身而且提供callback,當一個action製造器爲dispacther提供了一個新的action時,程序中全部的stores經過
註冊表中的回掉函數接收到這個action
隨着程序的增加,Dispatcher變的更加劇要,由於它可用於經過以特定順序調用已註冊的回調來管理stores之間的依賴關係。Stores
能夠以聲明的方式等待其餘stores的完成,而後相應的更新本身。
Stores
stores包含應用程序狀態和邏輯。他們的角色與傳統 MVC 中的model有點類似, 但它們管理許多對象的狀態-它們並
不表明 ORM 模型所作的單個數據記錄。它們也不像Backbone的集合。除了簡單管理 ORM 樣式對象的集合以外,
store還管理應用程序中特定域的應用程序狀態。
例如, Facebook 的回望視頻編輯器使用了一個 TimeStore, 它跟蹤播放時間位置和回放狀態。另外一方面,
同一應用程序的 ImageStore 跟蹤圖像的集合。咱們的 TodoMVC 示例中的 TodoStore 相似於它
管理要執行的項目的集合。商店展現了模型集合和邏輯域的單一模型的特徵。
如上所述,store與dispacther一塊兒註冊, 併爲其提供回調。此回調將做爲參數接收該actions。在store的註冊回調中,
基於該actions類型的開關語句用於解釋actions, 併爲stores的內部方法提供適當的掛鉤。這容許actions經過Dispatcher程序導
致對stores狀態的更新。更新stores區後, 它們會廣播一個事件, 聲明其狀態已更改, 所以視圖能夠查詢新狀態
並進行更新。
Views and Controller-Views
ReactProvider爲視圖層提供了一種可組合和自由從新可呈現的視圖。靠近嵌套視圖層次結構的頂部, 一種特殊類型的視圖偵聽由它所依賴的stores所廣播的事件。
咱們稱之爲控制器視圖, 由於它提供了膠水代碼來從stores區獲取數據, 並將這些數據傳遞到其子代鏈中。咱們可能有一個Controller-Views管理頁面的任何重要部分。
當它從store接收事件時, 它首先請求經過store的公共 getter 方法所需的新數據。而後調用它本身的 setState () 或 forceUpdate () 方法,
致使其render () 方法和其全部子代的render () 方法運行。
咱們常常將整個store狀態從單個對象的視圖鏈中傳遞下來, 容許不一樣的後代使用他們須要的內容。除了在層次結構的頂部保持相似於控制器的行爲,
從而使咱們的子代視圖儘量地保持功能上的純淨, 在單個對象中傳遞stores的整個狀態也有減小道具數量的效果, 咱們須要管理。
有時, 咱們可能須要在層次結構中更深層次地添加更多的Controller-Views, 以保持組件的簡單。這可能有助於咱們更好地封裝與特定數據域
相關的層次結構的一部分。可是, 請注意, 控Controller-Views在更深層次結構中能夠經過引入一個新的、潛在衝突的數據流入口點來違反數據的奇異流。
在決定是否添加深層控制器視圖時, 應平衡較簡單組件的增益與多個數據更新在不一樣點上流入層次結構的複雜性。這些多數據更新可能會致使奇數效果,
而響應的渲染方法經過不一樣控制器視圖的更新重複調用, 可能會增長調試的難度。
Actions
Dispatcher公開了一種方法, 它容許咱們觸發對stores的Dispatcher, 幷包含咱們稱爲actions的數據負載。actions的建立可能被包裝成一個語義幫助器方法,
將該actions發送到Dispatcher程序。例如, 咱們可能但願在 "要執行的列表" 應用程序中更改要執行的項的文本。咱們將建立一個功能簽名,
如 updateText (todoId,new-Text) 在咱們的 TodoActions 模塊的行動。此方法能夠從咱們的視圖的事件處理程序中調用, 所以咱們能夠調用它
來響應用戶交互。此actions建立器方法還向actions添加類型, 以便在stores區中解釋actions時, 它能夠適當地響應。在咱們的示例中,
此類型可能被命名爲 TODO_UPDATE_TEXT 之類的內容。
actions也可能來自其餘位置, 如服務器。例如, 在數據初始化過程當中會發生這種狀況。當服務器返回錯誤代碼或服務器有更新提供給應用程序時,
也可能發生這種狀況。