redux 三重境

本文寫在去年8月,有著我對redux最佳實踐的思考和總結。

王國維的《人間詞話》的三重境

古今之成大事業、大學問者,必經過三種之境界。

  • 「昨夜西風凋碧樹,獨上高樓,望盡天涯路」,此第一境也;
  • 「衣帶漸寬終不悔,為伊消得人憔悴」,此第二境也;
  • 「眾里尋他千百度,驀然回首,那人卻在燈火闌珊處。」,此第三境也。

大綱

  1. redux 基礎知識和 react-redux
  2. redux 周邊生態探索
    • 有哪些功能?(粗略介紹)
    • 有哪些很不錯的第三方庫?(詳細介紹)
  3. 最佳實踐介紹(dva)

一: redux 基礎知識和 react-redux

  1. 三個基本原則
  2. 數據流
  3. 在 React 應用中使用 Redux(react-redux)

redux 三個基本原則

  1. 整個應用只有唯一一個 Store 實例
  2. State 只能通過觸發 Action 來更改
  3. State 的更改 必須寫成純函數(Reducer),(oldState, action) => newState,也就是每次更改總是返回一個新的 State

redux 兩個顯著的特點

  1. 可預測性(Reducer 是純函數)。
  2. 擴展性強(middleware)。

單向數據流

  1. Actions 是 store.dispatch(action),它是每次數據改變的源頭。
  2. 如果有 middleware 將先進入 middleware
  3. Reducer 管理 state, 也就是 (oldState, action) => newState 的集合。
  4. 當 state 改變後, View Provide 就會更改視圖

連接 React (react-redux)

  1. 使用 Provider 在根組件 注入 Store
  2. 容器組件使用 connect() 方法連接 Redux

1. 使用 Provider 在根組件 注入 Store

2. 容器組件使用 connect() 方法連接 Redux

那麼我們如何獲取容器組件的依賴呢?

容器組件及其子組件需要的兩個能力:

  1. 讀數據:獲取 redux 的 state
  2. 改數據:向 redux dispatch actions

使用步驟1

  1. mapStateToProps:從 store 的 state 里把容器組件依賴的部分 state 取出來,成為組件的 props。
  2. 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 的態度

  1. 學習借鑒
    • 學習思想,借鑒他們的最佳實踐; 持續跟進
  2. 使用? or 自己造輪子?
    • 使用: 當其比較成熟時,對於複雜頁面(尤其是單頁應用)可以考慮使用。
    • or 自己造輪子: 借鑒學習其的特點和功能自己造輪子

推薦閱讀:

前端每周清單第18期:Firefox、Chrome、React、Angular發布新版本;提升RN應用性能的方法
前端每周清單第10期:Firefox 53、React VR發布、JS測試技術概述、Microsoft Edge現代DOM樹構建及性能之道
實現一個 TodoList - Vue2 Tutorials (二)

TAG:前端开发 | React | 编程 |