還在糾結 Flux 或 Relay,或許 Redux 更適合你

重磅消息,Redux 1.0 發佈,終於能夠放心用於生產環境了!前端

Redux 1.0 Cheers

在這個端應用技術膨脹的時代,天天都有一大堆框架冒出,號稱解決了 XYZ 等一系列牛 X 的問題,而後過一段時間就不被提起了。但開發的應用仍是須要維護的!因此選擇框架時不要只顧着本身用着爽,還要想着之後別人接手時的難易度。react

由於 Flux 自己約定不夠細緻,如何作異步、如何作同構這些很是廣泛的問題,官方都沒有給出詳細的說明。還有 store,view 裏一大堆重複代碼,極速膨脹的 action 等問題。這也不免會冒出一堆「改良」性的輪子。有一些很是閃光,如 Redux,Reflux,Marty。Reflux 和 Marty 基本上只是去掉重複代碼併爲現有 Store,Action 增長一些靈活性,用起來比原生 Flux 上手更容易,可是整體兩者沒有跳出 Flux 的思想,大量依舊採用「傳統」的 mixin 方式實現。若是項目不是很複雜能夠試試。至於 Relay,因爲須要後端 GraphQL 支持,對於採用 REST 接口開發的遺留項目和先後端分離的大團隊來講成本切換有點高。git

如今開始說今天的主角 Redux。Redux 由 Flux 演變而來,後來受 Elm 啓發,去掉了 Flux 的複雜性,到如今愈來愈自成一派,甚至已經有了 Angular 的實現。最近開始把團隊舊的純 Flux 開發項目逐步往 Redux 上遷移。Redux 仍是秉承了 Flux 單向數據流Store is the single source of truth 的思想,這兩點略過。下面談一下使用 Redux 過程當中的其它感覺。github

特性和優勢

文檔清晰,編碼統一

Redux 文檔很是清晰細緻,這一點有助於統一團隊編碼風格,節省了不少糾結和踩坑的時間。不再糾結 Ajax 請求到底放哪裏了,所有丟到 action(通用的也能夠放到 middleware) 裏就沒錯。究竟使用 state 仍是 props?組件裏所有使用 props,只在頂層組件裏使用 state。以前爲了靈活或兼容性,Redux 的 provider 提供 Provider decorator 裝飾器 和 provider 兩種調用用法,如今只建議使用 Provider decorator。Redux 這點設計思想和 Python 的很是像:編程

There should be one, and preferably only one - obvious way to do it.redux

你會發現用了 Redux 後,整個團隊寫的代碼風格都比較一致,上一次有這種感覺是項目由舊的 jQuery 組件遷到 React 的時候。若是有些場景你仍是糾結怎麼辦?去 Redux issues 提個 issue 吧,很快就會有人回覆。後端

State, State, State -> Store

前端複雜性在於 view,view 複雜性在於 state 處理。state 複雜是由於包括了 AJAX 返回的數據、當前顯示的是哪一個 tab 等這些 UI state、表單狀態、甚至還有當前的 url 等。Redux 把這些全部的 state 彙總成一個大的對象,起了個名字叫 Store,沒錯,就是 Flux 裏的 Store。只是 Redux 限定一個應用只能有一個 Store。單一 Store 帶來的好處是,全部數據結果集中化,操做時的便利,只要把它傳給最外層組件,那麼內層組件就不須要維持 state,所有經父級由 props 往下傳便可。子組件變得異常簡單。app

Reducer

只有一個 Store,第一感受是這個 Store 對象會不會很是大?其實對象大並不可怕,可怕的是對象處理邏輯放到一塊兒。只要把這些處理邏輯按處理內容拆分不就能夠了嗎?!拆分後的每塊處理邏輯就是一個 Reducer。把這些 Reducer 裏的每塊內容合到一塊兒(用 ES6 的 import 語法)就組成了完整的 StoreReducer 只是一個純函數,因此很容易測試。提到 Reducer 不得不提函數式編程,reducer 本質就是作對象格式轉換,這點用函數式操做實在過高效了。框架

(previousState, action) => newState

由於是純函數,組合多個 reducer 很是簡單,參見 https://gist.github.com/gaearon/d77ca812015c0356654f。順便也移除了 Flux 裏最讓人詬病的 waitFor 語法。前後端分離

Action

Redux 的 action 與 Flux 中的相似,都是表達 view 要改變 store 內容的載體。Flux 是經過統一的 Dispatcher 分發 action,Redux 去除了這個 Dispatcher,使用 store 的 store.dispatch() 方法來把 action 傳給 store。因爲全部的 action 處理都會通過這個 store.dispatch() 方法,Redux 聰明地利用這一點,實現了與 Koa,Ruby Rack 相似的 Middleware 機制。Middleware 可讓你在 dispatch action 後,到達 store 前這一段攔截並插入代碼,能夠任意操做 action 和 store。很容易實現靈活的日誌打印、錯誤收集、API 請求、路由等操做。咱們團隊根據預創建的 action 和請求間的映射直接在這裏直接發 Ajax 請求,今後麻麻不再用擔憂我異步取數據了。

除了這些以外,還有逆天的 DevTools,可讓應用像錄像機同樣反覆錄製和重放。

Redux DevTools

對於同構應用 Redux 也有很好的支持,這一塊團隊正在調研,等實際上線後再作分享。

不足或不便

固然使用過程當中也有一些不順利的地方,其實主要仍是思想方面的轉變。

組件應儘量無狀態化

這也被稱爲 Smart Component 和 Dumb Component 之間的選擇,組件庫開發應儘量作成 Dumb Component。這一點和傳統的 jQuery 類廣泛使用命令式語法作組件開發有很大不一樣。如寫一個 Dialog,jQuery 組件通常會提供 dialog.show(), dialog.hide() 方法。但 Redux 要求顯示或隱藏應該被看成一個 props,由外部傳入來控制。Redux 比 Flux 更嚴格要求 Store 做爲數據來源的唯一性,因此以前能用的組件如今發現直接不能用了。

輪訓和 WebSocket 請求的處理

請求的發起要在 action 裏作,可是請求的暫停/啓動狀態要放到 store 裏,會增長一些複雜性,但保證了數據的一致性。其實仍是未明確 store 是單一數據源的思想。

資料:

官方地址:https://github.com/rackt/redux
中文文檔:http://github.com/camsong/redux-in-chinese
項目列表:https://github.com/xgrommx/awesome-redux
同構示例:http://react-redux.herokuapp.com/

對了,據說中文文檔翻譯的還不錯,連 Redux 做者 Dan Abramov 都推了,要不你也看看。有精力一塊兒參與翻譯,沒有精力給個 star 也行。

clipboard.png

原文地址

相關文章
相關標籤/搜索