標籤:

Flux架構模式

在說flux模式之前,我們先說說mvc和mvvm模式

MVC模式

通過關注數據界面分離,來鼓勵改進應用程序結構。也就是MVC將業務數據(model)與用戶界面(view)隔離,用控制器(controller)管理邏輯和用戶輸入。

MVC模式中的三種角色

Model

Model負責保存應用數組,和後端交互同步應用數據,或校驗數據。Model主要與業務數據相關,與應用內交互狀態無關

View

View是Model的可視化,表示當前狀態的視圖。前端View負責構建和維護DOM元素。更新Model的實際任務是在Controller上。用戶可以與View交互,包括讀取和編輯Model,在Model中獲取或設置屬性值。一個view通常對應一個model,所以在世實際開發過程中,會面臨多個view對應多個model的狀況

Controller

Controller負責連接view和model,model的任何變化會應用到view中,view的操作會通過controller應用到model中。

MVC的問題

MVC模式看上去沒有什麼問題,但是它存在一個十分麻煩的缺點,這個缺點隨著你的項目越來越大,邏輯複雜的時候非常的明顯,就是混亂的數據流動方式。

MVVM模式

MVVM的模式與MVC模式的最大區別在於數據綁定,也就是說view的數據狀態的改變直接影響VM,反之依然。

MVC模式帶來問題的解決方案

如果渲染函數只有一個,統一放在Controller中,每次更新渲染頁面,這樣的話,任何數據的更新都只用調用重渲染就行,並且數據和當前頁面的狀態是唯一確定的。但是重渲染會帶來嚴重的性能問題於用戶體驗問題。

而Flux也是解決這類問題的一種方案

Flux模式

Flux的核心思想就是數據和邏輯永遠單向流動

眾所周知,React提倡的是一種單向數據流,指的是父子組件之間的單向數據流。而Flux中的單向數據流則是在整體架構上的延伸。在Flux應用中,數據從action到dispatcher,再到store,最終到view的路線是單向不可逆的,各個角色之間不會像MVC模式中那樣存在交錯的連線

因為要實現單向數據流,所以在Flux模式中的dispatcher中定義了嚴格的規則來限定我們對數據的修改操作。只能通過dispatcher來修改store中的state,所以同時,store中不能不暴露setter,強化數據修改的純潔性。

上面談到的如果渲染函數只有一個後,即每次數據的更新都會調用重渲染,會十分的影響性能。在React中,通過Virtual DOM這個技術來進行優化性能,因為每次重渲染的是內存上的Virtual DOM,並由於PureRender保障從重渲染到局部渲染的轉換。

一個Flux應用由三大部分組成dispatcher,store和view

dispatcher負責分發事件

store負責保存數據,同時響應事件並更新數據

view負責訂閱store中的數據,並使用這些數據渲染相應的頁面

Flux的不足

雖然Flux的中心化控制十分優雅。但是它最大的問題就是Flux的冗餘代碼太多。雖然Flux源碼中幾乎只有dispatcher的實現,但是在每個應用中東需要手動創建一個dispatcher的實例,而且在一個應用中含有多個store。

基於Flux思想的Redux

Redux是基於Flux架構思想的一個庫的實現,它主要的核心運作流程為:

Redux與Flux的區別

Redux中只有一個store,而Flux中有多個store來存儲應用數據,並在store裡面執行更新邏輯,當store變化的時候再通知controller-view更新自己的數據,Redux是將各個store整合成一個完整的store,並且可以根據這個store來得到完整的state,而且更新的邏輯也不再store中,而是在reducer中。

Redux沒有Dispatcher這個概念。它使用的是reducer來進行事件的處理,reducer是一個純函數 (preState, action) => newState ,在Redux應用中,可能有多個reducer,每一reducer來負責維護應用整體state樹中某一部分,多個reducer通過combineReducers方法合成一個根reducer,來維護整個state

如圖的比較

Flux

Redux

Redux設計和使用的三大原則

單一的數據源

在Redux的思想里,一個應用永遠只有唯一的數據源,使用單一數據源的好處在於整個應用狀態都保存在一個對象中,我們隨時可以提取出整個應用的狀態進行持久化,這樣的設計也為SSR提供了可能

狀態是只讀的

狀態是只讀的這個和Flux的思想相同,但是Redux中還限制了store的setter從而限制修改應用狀態的能力。在Redux中,我們不會用代碼來定義一個store,而是通過reducer,通過當前觸發的action來對當前應用的state進行迭代,這裡沒有直接改變應用的狀態,而是返回了一個全新的狀態。

狀態修改均由純函數完成

在Flux中,是通過dispatcher的dispatch來觸發action,不僅產生了冗餘代碼,而且直接修改了store中的數據,無法保存每次數據變化前後的狀態,在Redux中,通過純函數reducer來確定狀態的改變,因為reducer是純函數,所以形同的輸入,一定會得到相同的輸出,這樣的話,返回的是一個全新的state,可以跟蹤每一次觸發action而改變狀態的結果成為了可能,也就是可以達到炫酷的time travel 調試方法。

?? Thats all~ (Github,歡迎star、follow、交流)??


推薦閱讀:

React 實現一個漂亮的 Table
前端每周清單第 10 期:Firefox53、React VR發布、JS測試技術概述、Microsoft Edge現代DOM樹構建及性能之道
redux源碼分析
基於Decorator的組件擴展實踐
redux-saga 實踐總結

TAG:Redux | Flux | React |