寫在前面
在開始全新的
React
項目前,先好好研究一下React
兩個典型的“輪子”,Reflux和Redux。兩者沒有明確的優劣之分,只是對初學者來說Reflux
容易理解,而Redux
的單一state
在項目開發中非常好用,所以你可能發現Github
上Redux
的星星比Reflux
略多些吧。但是見智者見智,兩者其實都是社區同仁智慧的結晶。
Redux
先談談對Redux
的理解。
獨特性
第一
一個數據層的framework
,類似於Baobab
。比其好的一點,引入middleware
體系,有幾個現成的插件redux-thunk
, redux-promise
,不用但心異步請求的事。雖然說靈活、獨立很重要,但全局設計也是 讓人放心去用,而不用擔心功能缺失和其它風險。
第二
應用了FP中數據不可變性(immutable),這讓追蹤數據改變過程有很大提升。也就是其宣揚的時間旅行。這對複雜問題定位是有好處的。
第三
樹形化數據存儲,reducer
的返回即是其新建,更新、刪除過程,樹形結構不需要預先定義。同時,reducer
也是純函數,與reactor
的render
是純函數呼應。
第四
強約束(約定),增加了內聚合性。Flux
中的action
, dispatcher
, store
比較散,在分層架構是需要的,但內聚性不佳,出現java
的儀式感。而Redux
是數據層很清晰,一個store
,更新則dispatch
到action
,前半段自己想怎麼搞就怎麼搞(middleware
),後半段reducer
。reducer
約束是不要改oldState
,返回newStatew
,做到immutable
。
第五
不一樣的action
:Redux
中的action
會切得很細,一個傳統的Action
被切成了三個Action
:Loading
, GetSuccess
, GetError
。所以,從這個方面來看Action
服務於UI,而非業務邏輯單元。
第六
Redux
大量應用FP,經常遇到FP中的curry
, trund
, promise
這些概念,學習成本較高。在middleware
層實現,對沒有FP經驗的人講不友好。
置Redux於上下文中
Redux
是一個比較薄的數據層。同時,把View同步刷新也做了(redux-react
)。
在傳統MVC中,還是有一個controller
來做業務邏輯。但Redux
硬生生的把一個controller
切成二部分:action
, reducer
。
理論上,Redux
還可以把React
組件中的state
的存儲也拿過來,比如用戶搜索的名稱。這樣,就可以把過濾算法放到selector
中去。但這樣好處並不是很大。
對比其他方案
與Baobab
對比,兩者都是數據管理框架,Baobab
提供cursor
來方便你對很深層的數據結構進行update
。而Redux
是通過selector
函數來做,這種方法會比較晦澀。但比Baobab
好的地方,做數據fetch
可以通過Redux
的middleware
來完成。
與Rails
的controller
, ActionRecord
相比,Redux
更多是一種約定,不提供路由級的controller
,不提供數據訪問cursor
。
Redux
接口不超過10個,代碼也非常少,但是與之前的MVC框架完全不同。可能最大的問題是沒有和react-route
打通,在工程化時讓人迷茫。
挑戰
Redux
應用最大的挑戰更多來自設計層面,如何設計action
,設計state
樹形結構。我們只能通過非常少的線索(FP架構思想)去做,這對沒有FP經驗的團隊是一個大挑戰。
通過selector
函數從stat
樹裏取數據比較晦澀,並且這個selector
裏的代碼認爲是業務邏輯,單獨放在selector
,業務上不內聚。
middleware
層設計:action
是一個意圖(intent),發送給middleware
,讓其來實現此意圖。但這樣做,action
比有兩義性,一會兒是對象,一會兒是函數。同時FP編程侵入性太大。
沒有與Route
結合起來設計,讓人很不放心,也不知道如何在不同路由下來做數據與組件的connect
。
OO與FP編程範式對決
react + redux是一種典型的FP編程範式實現,而其它框架大多是OO範式。是否選用react+redux開發,需要看是否對FP有掌握或者有一定的架構能力。但單獨用react則沒有這種要求,當個view來用。
FP優缺點
FP的好處是沒有OO的複雜儀式感,是沿着數據結構+算法的思路進行抽象和結構化。如果頂層設計做好,代碼複用度極高,代碼量少。比如要生成一顆樹我用迭歸算法直接生成,而OO的人往往會用一個Composite模式去定義一個晦澀的類接口。
FP的缺點也是也是面向過程編程的缺點,算法與數據全局化、並且互相耦合,這往往會導致一個強耦合的系統。如果沒有做好頂層設計,是難以演進的。
通過約定和全局的理解,可以減少FP的一些缺點。“約定大於配置”也是框架的主要發展方向。
OO優缺點
OO的好處是分而治之,增量演進。同時有自閉性,語義比較清晰。
缺點是在表達一些算法時,反而是很困難的。如command模式實現歷史回滾就挺麻煩。也這是四人幫的設計模式大多比較難以理解的原因。另外,OO一直有一個對算法複用的問題,ruby語言解決比較好,用mixin很自然。而像C++就用多繼承和泛型,個人感覺並不是最好的。
建議
有FP經驗的或者架構能力比較強,團隊人員比較少、能力強,較強適合用react+redux
。不然用react+angluar
, 或直接用vue
。而且過度的OO,搞太多java
儀式感確實沒有必要。通過架構設計,FP在生產力有着一定的優勢。同時對付複雜系統,能更好調測、定位問題。在新時代下,值得嘗試。
Reflux 和 Redux
已經認識了Redux
,而相比較Redux
而言,Reflux
沒有reducer
的概念,取而代之,和action
做基友的是store
。Reflux
的功能流程如下:
組件就是用戶界面,actions就是組件的動作,store用於執行actions的命令,並返回一個state對象給組件。組件通過state來更新界面。
而Redux的流程如下:
state就是數據,組件就是數據的呈現形式,action是動作,action是通過reducer來更新state的。
Reflux沒有把狀態的一部分值綁定在組件的props
上,而是將狀態綁定在組件的state
上,請看 react dev tool
的截圖:
Reflux
可以直接調用action
的方法,而Redux
必須將方法綁定在組件的props
上,或者使用props
的dispatch
方法來執行actions
的方法。
@參考 百草趙斌
《深入理解React、Redux》
@參考 天可
《react+relux入門教程》