精益 React 學習指南 (Lean React)- 1.6 Flux

書籍完整目錄javascript

1.6 flux

圖片描述

這一節將介紹 React 的核心應用架構模式 Flux,包括內容:前端

  • Flux 介紹java

  • MVC 架構之痛git

  • Flux 的理解github

  • Flux 相關庫和工具介紹編程

  • Flux 與 React 實例redux

最後咱們將會把以前的 TODOMVC 改成 Flux 的架構。segmentfault

1.6.1 Flux 介紹

簡單來說,Flux 是 Facebook 引入到 React 中的一種前端架構,經過定義其核心單向數據流的方式,讓 React 應用更加健壯。同時,這種應用架構也具備普適性,能夠應用到其餘任意前端項目中,甚至能夠應用到客戶端應用開發中,也就是說 Flux 更應該叫作一種架構模式(Pattern)。後端

1.6.2 MVC 架構之痛

在詳細介紹 Flux 以前,咱們先來看看傳統的前端 MVC 架構以及其帶來的問題。架構

MVC 的實現可能有不少種方式,比較靈活,但基本本質不會改變,只是三者間的數據傳遞方向可能會改變,即使是 MVP 模式也只是 MVC 的變種,因此爲了統一咱們且如下圖的 MVC 方式來討論。

圖片描述

概念

  • Model: 負責保存應用數據,和後端交互同步應用數據

  • View: 負責渲染頁面 HTML DOM

  • Controller: 負責鏈接 View 和 Model , Model 的任何改變會應用到 View 中,View 的操做會經過 Controller 應用到 Model 中

  • 關係:Model, View, Controller 都是多對多關係。

流程

以 TODOMVC 爲例子用戶添加一個 todo 的交互流程:

View -> Action -> Controller -> Model -> View

  1. View -> Action: 添加按鈕事件或者 input 輸入的提交事件

  2. Action -> Controller: 控制器響應 View 事件

  3. Controller -> Model: 控制器依賴 Model, 調用 Model 添加 todo

  4. Model -> View: View 監聽 Model 的改變添加 todo 事件,在 HTML 中添加一個新的 Todo 視圖

問題

對於新增一個 todo ,須要編寫一個視圖渲染處理函數,函數內添加新項目到列表中。同理對於刪除一個 todo,也會有一個處理函數。當業務邏輯變多事後,可能有不少模型須要作增刪改的功能,與之對應的就是咱們須要精心構建這麼多的渲染處理函數。 這種局部更新模式是高性能的關鍵所在,但問題是:

  1. 更新邏輯複雜,須要編寫大量的局部渲染函數

  2. 問題定位困難,頁面的當前狀態是有數據和這些局部更新函數肯定的

如何解決

若是渲染函數只有一個,統一放在 App 控制器中,每次更新重渲染頁面,這樣的話:

  1. 任何數據的更新都只用調用重渲染就行

  2. 數據和當前頁面的狀態是惟一肯定的

重渲染也有弊端,會帶來嚴重的性能問題,重渲染和局部渲染各有好壞,對 MVC 來講這是一個兩難的選擇,沒法作到魚和熊掌兼得。

那如何才能兼顧兩種模式的優勢?

1.6.3 Flux 架構

經過 React + Flux 就能夠完美解決 MVC 的問題。

  1. 重渲染: 在 React 中每次渲染都是重渲染,且不影響頁面性能,是由於重渲染的是 Virtual Dom。這就意味着徹底不用去關係重渲染問題,增刪改的渲染都和初始化渲染相同入口

  2. 數據和狀態一致性: Store 的數據肯定應用惟一的狀態

簡單來講在 Flux 架構中直接剝離了控制器層,MVC 架構變成了 MV + Flux 架構。

概念

單向數據流

圖片描述

這是 Flux 架構的核心思想,重上面的圖中能夠看到,數據的流向從action 到 view 的一個單向流。

Action

圖片描述

Action 能夠理解爲對應用數據修改的指令,任何修改應用數據的行爲都必須需經過觸發 action 來修改。Action 能夠來自於 View,也能夠來自服務端的數據更新。

Action Creator

圖片描述

爲了抽象 Action ,提供一些輔助的語義化的方法來建立 Action,這些輔助方法叫作 Action Creator。

Stores

圖片描述

應用的數據中心,全部應用數據都存放在這裏控制,同時包含數據的控制行爲,可能包含多個 store

Dispatcher

圖片描述

action 的控制者,全部 action 都會經過 dispatcher,由 dispatcher 控制 action 是否應該傳入到 store 中,Dispatcher 是一個單例。

View

圖片描述

頁面的視圖,對應 React 的 Component, 視圖能夠觸發 action 到 dispatcher。

須要區別出一種叫控制器 View(Controller View)的類型,這種 View 能夠知曉 store 數據,把 store 數據轉化爲自身的狀態,在將數據傳遞給其餘 view 。 而且能夠監聽 store 數據的改變,當 store 數據改變事後從新設置狀態觸發重渲染。 能夠將控制器 View 對應 MVC 中的控制器,可是差異很大,控制器 View 惟一多作的事情就是監聽 store 數據改變,沒有其餘任何業務處理邏輯。

流程

一樣以 TODOMVC 的添加 todo 爲例,Flux 中的流程爲:

View -> Action(Action Creator -> Action) -> Dispatcher -> Store -> Controller View -> View

  1. View -> Action: 添加按鈕事件或者 input 輸入的提交事件,View 中將事件轉化爲 action, action 由 Action Creator 建立。

  2. Action -> Dispatcher: action 統一由 Dispatcher 分配

  3. Dispatcher -> Store: Dispatcher 分配 action 到 Store

  4. Store -> Controller View: 控制器 View 監聽 store 的數據改變,將數據轉化爲自身屬性

  5. Controller View -> View: 數據改變自動重渲染全部視圖

對比

  1. 渲染策略: 數據改變 Flux 自動渲染,MVC 手動編寫更新函數

  2. 事件觸發策略: Flux 中全部 action 交給 dispather 分配,MVC 中交給對應的控制器分配

Flux 在覈心策略上的不一樣是解決 MVC 架構問題的關鍵

1.6.4 理解 Flux 架構

Flux 架構是很是優雅簡潔的,合理利用了一些優秀的架構思惟

分而治之(Divide And Conquer)

數據的處理過程是 Store -> Controller View -> View。 全部數據來自於 Store,頁面的渲染層級爲 Store 將數據傳入 Controller View, 再由 Controller View 傳入子 View , 一直到 View 的葉子節點。

這個是一個典型的分而治之策略,將大的頁面拆分爲小的模塊,再由小的模塊拆分爲小的組件,具體組件負者組件自身的問題,全部子組件都是自私的,不用關心「你們」,只用關心「小家」。

合而治之 - 中心化控制

Flux 把全部的 View 都視做愚民,Store 視做資源的擁有者爲統治者,統治者須要提供資源(數據)給平民,可是若是平民企圖對資源修改(Mutation),必須得先通知給統治者,讓統治者決定是否作處理。

咱們爲 Flux 中的概念分配角色

  • View: 平民

  • Action: 資源修改操做

  • Dispatcher: 審覈官

  • Store: 統治者

一個企圖修改資源的操做能夠描述爲:

View Require Mutation -> Action -> Dispatcher -> Store -> Mutate Handler

平民提交 Mutation 請求,由審覈官控制,審覈經過後遞交給統治者,統治者再分配給親信作資源 Mutation

合而治之的策略也等於中心化控制策略, 做爲統治者既要懂得放權利(資源的分配),也要懂得控制權利(資源的修改),這種收縮自如的合理性是 Flux 簡潔的根本。

同時這種思惟帶來的優勢以下:

  1. View 的獨立性和簡單性:View 自身的邏輯簡單,不須要知道太多事情,只關心上級傳來的數據,這種模式使得 View 是低耦合的,簡潔的。

  2. 高可維護性:中心化控制知道全部對資源的操做,若是發生 bug, 能夠很快定位問題

函數式編程思想

在 Flux 中數據的單向流動依賴於 View 的肯定性,相同的數據傳入相同的組件,獲得的結果必然要相同,這是函數式編程的思想。

函數式編程中的純函數(Pure Function)定義以下:

純函數是這樣一種函數,即相同的輸入,永遠會獲得相同的輸出,並且沒有任何可觀察的反作用

如:

// 純函數,相同的輸入一定有相同的輸出
function pure(a, b, c) {
    return a + b + c;
}

// 非純函數,咱們永遠沒法肯定 this.a 會變成什麼
function notPure(b, c) {
    return this.a + b + c;
}

爲了保證組件也能作到 「純函數」 的特性,相同的屬性會獲得相同的渲染結果。 在寫 React 組件的時候儘可能準守一下約定:

  1. 儘可能使用無狀態組件

  2. 除了控制類組件之外其餘組件避免使用組件狀態

  3. 能夠經過屬性計算出來的狀態不要用狀態來表示

  4. 組件的渲染避免外部依賴,按照純函數的方式寫

函數式的優勢也是無反作用組件的優勢:

  1. 無耦合,可移植性強: 組件可重用性高

  2. 可測試性高:組件無依賴,能夠很容易的單獨測試組件

1.6.5 Flux 生態

上面已經講過 Flux 更應該算是 Facebook 提出的一種前端架構模式,而根據這種理念的 Flux 實現有不少,如下是 github star 數較高的一些實現:

  1. Facebook 官方實現

  2. Redux 目前承認度最高的實現

  3. refluxjs

  4. alt

  5. fluxxor

後面咱們會在第四章中專門講解 Redux 與 React 的應用。

1.6.6 Flux 與 React 實例

@todo

相關文章
相關標籤/搜索