redux 三重境
本文寫在去年8月,有著我對redux最佳實踐的思考和總結。
王國維的《人間詞話》的三重境
古今之成大事業、大學問者,必經過三種之境界。
- 「昨夜西風凋碧樹,獨上高樓,望盡天涯路」,此第一境也;
- 「衣帶漸寬終不悔,為伊消得人憔悴」,此第二境也;
- 「眾里尋他千百度,驀然回首,那人卻在燈火闌珊處。」,此第三境也。
大綱
- redux 基礎知識和 react-redux
- redux 周邊生態探索
- 有哪些功能?(粗略介紹)
- 有哪些很不錯的第三方庫?(詳細介紹)
- 最佳實踐介紹(dva)
一: redux 基礎知識和 react-redux
- 三個基本原則
- 數據流
- 在 React 應用中使用 Redux(react-redux)
redux 三個基本原則
- 整個應用只有唯一一個 Store 實例
- State 只能通過觸發 Action 來更改
- State 的更改 必須寫成純函數(Reducer),(oldState, action) => newState,也就是每次更改總是返回一個新的 State
redux 兩個顯著的特點
- 可預測性(Reducer 是純函數)。
- 擴展性強(middleware)。
單向數據流
- Actions 是 store.dispatch(action),它是每次數據改變的源頭。
- 如果有 middleware 將先進入 middleware
- Reducer 管理 state, 也就是 (oldState, action) => newState 的集合。
- 當 state 改變後, View Provide 就會更改視圖
連接 React (react-redux)
- 使用 Provider 在根組件 注入 Store
- 容器組件使用 connect() 方法連接 Redux
1. 使用 Provider 在根組件 注入 Store
2. 容器組件使用 connect() 方法連接 Redux
那麼我們如何獲取容器組件的依賴呢?
容器組件及其子組件需要的兩個能力:
- 讀數據:獲取 redux 的 state
- 改數據:向 redux dispatch actions
使用步驟1
- mapStateToProps:從 store 的 state 里把容器組件依賴的部分 state 取出來,成為組件的 props。
- mapDispatchToProps: 將特定的 dispatch 函數取出來變為 props 。
註: bindActionCreators 將 ActionCreator 和 store 的 dispatch 綁定到一起,返回一個特定的 dispatch 函數,組件調用即可觸發 store.dispatch(action)
使用步驟2
在 render 等函數裡面 取出相應 props,自己使用或者傳給子組件
分離容器組件和展示組件
redux 的重要思想:分離容器組件和展示組件。
容器組件
在應用中,只有 最頂層組件是對 Redux 可知。
展示組件
應該是「笨拙」的,是通過父組件傳遞的 props 來獲取數據和更改數據的 dispatch,它是感知不到 redux 存在的,具有很強的復用性。
如何分辨容器組件和展示組件的思考
1. 狀態
- 容器組件維護多個狀態
- 展示組件維護極少的狀態(一般是 ui 狀態)
2. ui
- 容器組件無關 ui,幾乎沒有 css 樣式、html 標籤,通過組合展示組件來構造容器組件
- 展示組件 ui 強相關,大量 css 和 html 標籤
容器組件示例(ArticleBox 組件):
展示組件示例(Article 組件):
容器組件和展示組件對比
二: 探索階段
- 探索 redux 生態
- 有哪些功能?(粗略介紹)
- 有哪些很不錯的第三方庫?(詳細介紹)
- 最佳實踐介紹(dva)
redux 生態
- 連接到其他庫
- 開發(debug)工具
- 各類實用工具
- 簡化 api
- 計算、處理數據
- 非同步 action
連接到其他庫
- react-redux
- react-router-redux
- redux-immutablejs
實用工具
- redux-thunk — 用最簡單的方式書寫非同步 action creator
- redux-actions — 在初始化 reducer 和 action 構造器時減少樣板代碼
- Reselect Data => View store 的 select 方案,用於提取數據的篩選邏輯。
- 等等
開發測試工具
devtool
redux-devtools — 一個使用時間旅行 UI 、熱載入和 reducer 錯誤處理器的 action 日誌工具
DevTools accepts monitor components(Custom Monitors)
Redux Logger
- redux-logger — 記錄所有 Redux action 和下一次 state 的日誌
我這裡就介紹一個第三方庫
- redux-action
簡化 redux api
redux-actions — 在初始化 reducer 和 action 構造器時減少樣板代碼
createAction
下圖這是 createAction 的效果 (我把我博客的 actions refactor 一下,上面是簡化後。)
??
內部實現
原理就是高階函數, createAction 返回一個函數,
三: 最佳實踐dva 介紹
google dva...第一個結果
dva 框架
實際上 dva 是基於現有應用架構 (redux + react-router + redux-saga 等)的一層輕量封裝,沒有引入任何新概念,全部代碼不到 100 行。
由支付寶前端團隊開發。
他們總結的 React + Redux 最佳實踐
dva 的由來
- React + Redux 最佳實踐 (dva 基於此封裝)
- 支付寶前端應用架構的發展和選擇: 從 roof 到 redux 再到 dva
dva 特點
api 風格方面非常像 vue,並且沿襲了 vue 的簡單易上手、api 簡潔的特點。
dva 使用
關於 dva 的思考
react redux
react redux 的思想從一開始就是 開放的,海納百川,官方給出的最佳實踐是 組合式 的,根據需求、喜好的不同,會有十幾種最佳實踐。。。。
- 優點:社區異常活躍;擴展性強、非常靈活;中台組件庫基於 React。
- 缺點:學習成本高,新手上手慢;太靈活,周邊生態百花齊放,如果沒有一定的約束,非常不易於團隊合作。
vue
去年開始 vue 以上手容易、api 簡潔優雅出名,對於同類需求,官方給出的最佳實踐幾乎是唯一的。
- 優點:學習成本低,易上手;最佳實踐統一,利於團隊合作;作者非常給力,在 vue2.0 里,發布了很多特別棒的新 feature(jsx,virtual dom,伺服器流式渲染); weex 擴展了 vue 在移動端的能力。
- 缺點:社區活躍低於 React;擴展性、靈活性差。
dva
dva 結合了 react 和 vue 兩者的優點
- 學習成本低,易上手
- 最佳實踐統一,利於團隊合作
- 社區異常活躍,擴展性強
- 中台 dpl 基於 React
缺點:
- 降低了 redux 的擴展性、靈活性
對 dva 的態度
- 學習借鑒
- 學習思想,借鑒他們的最佳實踐; 持續跟進
- 使用? or 自己造輪子?
- 使用: 當其比較成熟時,對於複雜頁面(尤其是單頁應用)可以考慮使用。
- or 自己造輪子: 借鑒學習其的特點和功能自己造輪子
推薦閱讀:
※前端每周清單第18期:Firefox、Chrome、React、Angular發布新版本;提升RN應用性能的方法
※前端每周清單第10期:Firefox 53、React VR發布、JS測試技術概述、Microsoft Edge現代DOM樹構建及性能之道
※實現一個 TodoList - Vue2 Tutorials (二)