狀態管理之 Redux & React Redux

原文地址: https://monster1935.com/2019/...

在進行 React 技術棧的一些技術方案的「挖墳」過程當中,有這樣一個體會:爲何須要這樣一個方案,是遇到了什麼的問題,引入該方案會帶來什麼樣的收益。任何技術方案的引入都對應了某些技術場景下遇到的問題。javascript

Vue 的開發中引入了狀態管理方案 Vuex,Vuex 的引入可有效下降組件之間的通訊複雜度同時還提供了全局狀態管理的能力,對於一箇中大型平臺來講,引入狀態管理方案勢在必得。html

遇到的問題

討論任何技術方案,都要從遇到的問題場景入手。在 Redux 的原做者 Dan Abramov
You Might Not Need Redux 一文中闡釋了這個思想,是否是必定要用 Redux,不是的。什麼場景下,什麼問題下能夠引用這個技術方案,是咱們在考慮一些技術方案選型落地時的必需要考慮的一個問題。java

咱們遇到了什麼問題?react

Redux 中文文檔「動機」一章中作了總結。大體有這麼幾個問題:git

  1. 中大型單頁應用的開發中,隨着應用複雜度的提高,狀態愈來愈多
  2. 狀態的更改場景愈來愈多,包括用戶交互,異步請求,組件之間的通訊等
  3. 狀態更改不可控,遇到問題很差排查

如何解決這些問題,就須要有一個統一的解決方案,最關鍵的一點:狀態可控易管理github

顯然,Redux 就是來作這些事情的。redux

從 Redux 的三大原則中咱們就能夠看出來,Redux 就是完成狀態的可控易管理。性能優化

1、 單一數據源(store)數據結構

整個應用的 state 被存儲在一個 store 中,管理方便,對於服務端渲染有較大優點(就是你們常說的同構應用)。app

2、 state 只讀

state 不能直接被修改,必須 dispatch action 去修改。一個 action 就是一個js對象,描述即將發生的事情和要攜帶的參數。這個原則保證了狀態的修改可控

3、經過純函數(pure function)去修改 state

純函數有個特色,整個過程當中不產生任何反作用,固定的輸入必產生固定的輸出。此舉保證了 state 變動的可追蹤性。

以上,咱們也就理解了 redux 這個庫在 github 上的介紹

Predictable state container for JavaScript apps
(一個爲 js 應用而生的可預測的狀態容器)

Redux 都作了什麼

import { createStore } from 'redux'

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([action.text])
    default:
      return state
  }
}

let store = createStore(todos, ['Use Redux'])

store.dispatch({
  type: 'ADD_TODO',
  text: 'Read the docs'
});

store.subscribe(() => {
  // do your update
  console.log(store.getState())
})

如上所示,這是一個最簡單的 Redux 的使用示例。主要作了這幾件事情:

  1. 建立一個全局 store,注意 redux 是單一數據源思想,所以在一個應用中使用一個 store 便可
  2. store 中獲取 state 經過 store.getState()
  3. 想要改變 state 經過 dispatch 一個 action, action 是一個用來描述此次動做的 js 對象,裏面包含了 action 的 type 和 payload,這裏能夠衍生出 action creator 的概念,一個函數專門用來產生 action。
  4. 一個 reducer 專門負責更新 state,經過判斷不一樣的 action type,操做不一樣的state返回。注意這裏不要直接操做 state, 而是 clone 一份,而後返回一個全新的 state,此處能夠衍生出一些其餘的數據結構的操做方案,如 immutable 方案。

經過以上咱們能夠發現,這是一個徹底解耦的狀態管理方案,不依賴於其餘的任何庫,一個純 javascript 實現。在這一點上,和 Vuex 有着本質上的區別。也就是說 Vuex 只能是在 Vue 的全家桶中使用,是一個上層的狀態管理方案。Redux 不一樣,它能夠和任何 javascript 應用開發結合使用。那麼在 React 中如何集成 Redux 呢,這就是接下來咱們要討論的 React Redux。

React Redux

React Redux 是一個在 React 中使用 Redux 方案的庫。爲何引入一個狀態管理方案,除了引入 Redux 還要引入 React Redux?

咱們須要從 React Redux 所作的事情入手。React Redux作了什麼?

  1. 每一個組件均可以 dispatch action 更改 state
  2. 每一個組件都只拿本身關心的 props 進行渲染
  3. 每一個組件均可以獲取全局的 store 實例
  4. 全局狀態的更改的訂閱,獲取最新的 state
  5. 一些性能優化,避免一些沒必要要的 re-render 過程

綜上幾點,咱們能夠大體感知 React Redux 所作的一些事情,將一些通用的代碼進行封裝,暴露出 API 以簡化在 React 中的使用。

有這麼幾個概念比較重要。

1、Provider

一個包含組件,接收 store 參數,子組件中均可以經過 connect 方法得到 store

2、connect()

一個高階函數,返回一個 React 組件,主要作了如下兩件事情:

  1. mapState,將 store 中 state 以 props 的形式傳遞給被 connect 的組件,
  2. mapDispatch,將 store 中的 action 以 props 的形式傳遞給被 connect 的組件,這其中還作了不少封裝,能夠容許咱們直接傳遞 action creator,在使用的時候省去 dispatch 的過程

總結

以上僅僅是一個針對 Redux 和 React Redux 的大體輪廓。這個過程當中還有幾個問題沒有討論:

  1. Redux 中僅僅能夠 dispatch 一個 action 去更新 state,如何將一些帶反作用的過程進行封裝,這就要討論到 React 的中間件機制
  2. React Redux 中的性能優化都作了哪些事情

Redux 目前的維護者 Mark EriksonIdiomatic Redux: The History and Implementation of React Redux 一文中針對 React Redux 的 API 版本迭代過程當中進行了很透徹的分析,推薦。

參考連接

  1. https://www.redux.org.cn/docs...
  2. https://blog.isquaredsoftware...
  3. https://medium.com/@dan_abram...
相關文章
相關標籤/搜索