Flux架構模式
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 實踐總結