Redux設計思想與使用場景

歡迎關注個人公衆號睿Talk,獲取我最新的文章:
clipboard.png前端

1、前言

Redux 做爲 React 全家桶的一名重要成員,在衆多大牛的力薦之下獲得了普遍的應用,Github 上的 Star 也達到 42k 之多!然而,當觸及最根本的問題,爲何要使用 Redux 的時候,不少人是說不清楚的。本文嘗試解讀 Redux 的設計初衷,並結合 React 談談實際的使用場景。本文只談理論,不會對 Redux 的使用做過多的介紹。segmentfault

2、Redux 設計思想

如何用一句話來描述 Redux ?官網是這麼寫的:設計模式

Redux is a predictable state container for JavaScript apps.
Redux是一個爲JavaScript應用設計的,可預測的狀態容器。

因而可知,Redux的主要做用是管理程序狀態的。這裏所說的狀態指的是數據狀態,也就model的狀態( state )。當今流行的前端框架,都是使用 MVVM 的設計模式,也就 Model,View,View-Model。框架承擔了大部分 View-Model 的工做,咱們只須要把 Model 和 View 的映射關係定義清楚就行。用公式描述就是View = Render(Model)。因此本質來講,用戶看到的頁面,是Model 在某個狀態下的視覺呈現。數組

clipboard.png

頁面的切換,能夠簡單理解爲 Model 的狀態變遷(同時也會涉及到 UI 的狀態變遷)。數據的狀態和 UI 的狀態,下文統一稱爲 state。前端框架

那麼,爲何須要專門有一個工具來管理 state 呢?先來看看下面這張圖:服務器

clipboard.png

這是一張backbone的數據流圖,一個 View 可能涉及到多個 Model,當用戶操做 View 的時候,可能引起多個 Model 的更新,而 Model 的更新又會引起另外一個 View 的改變。View 與 Model 之間的關係錯綜複雜,若是想要添加一個功能或者修改 bug,都要花大量的時間進行調試,還容易出問題。網絡

你也許會說,使用 React 就不會遇到這種問題,由於 React 自然就是使用 state 來管理界面的展現,state 與 View 一一對應,這與 Redux 的思想是契合的。然而,隨着應用複雜度的增長,你會經歷如下心路歷程:app

  • 剛開始的時候,只須要作一些簡單的展現,只要在頂層的組件獲取數據後再以 props 的形式傳給子組件就行了:

clipboard.png

  • 當加入交互功能後,兄弟組件之間須要共享 state 了,當組件一修改後組件二也要同步更新。React 的解決方案是狀態提高(Lifting State Up),經過父組件來統一更新 state,再將新的state 經過 props 傳遞下去:

clipboard.png

  • 隨着功能的不斷豐富,組件愈來愈多,state也愈來愈複雜,直到有一天你發現,修改和共享某個state變得極其艱難:

clipboard.png

共享的state須要放在最頂層維護,而後一層一層地往下傳遞修改state的方法和展示的數據。這時你會發現,不少數據中間層的組件根本不須要用到,但因爲子組件須要用,不得不通過這些中間層組件的傳遞。更使人頭疼的事,當state變化的時候,你根本分不清楚是由哪一個組件觸發的。框架

  • 這時候若是使用Redux對應用進行重構,狀態的變化就會變得很是清晰:

clipboard.png

應用的state統一放在store裏面維護,當須要修改state的時候,dispatch一個action給reducer,reducer算出新的state後,再將state發佈給事先訂閱的組件。分佈式

全部對狀態的改變都須要dispatch一個action,經過追蹤action,就能得出state的變化過程。整個數據流都是單向的,可檢測的,可預測的。固然,另外一個額外的好處是再也不須要一層一層的傳遞props了,由於Redux內置了一個發佈訂閱模塊。

clipboard.png

3、使用場景

Redux雖好,但並不適用於全部項目。使用Redux須要建立不少模版代碼,會讓 state 的更新變得很是繁瑣,誰用誰知道

正如 Redux 的做者 Dan Abramov 所言,Redux 提供了一個交換方案,它要求應用犧牲必定的靈活性以達到如下三個要求:

  • 經過簡單對象和數組描述應用狀態
  • 經過簡單對象描述應用狀態的改變
  • 使用純函數來描述狀態改變的邏輯

相應的,你會獲得如下好處:

  • 能夠很方便的將 state 存儲到 Local Storage 中並在須要的時候取出並啓動應用
  • 能夠在服務器端直接計算出 state 再存到 HTML 中,而後在客戶端秒開頁面
  • 方便的序列化用戶操做和對應的 state 快照,在出現 bug 的時候能夠利用這些信息快速復現問題
  • 經過在網絡中傳遞 action 對象,能夠在對代碼進行很小改動的狀況下實現分佈式應用
  • 能夠在對代碼進行很小改動的狀況下實現撤銷和恢復功能
  • 在開發過程當中能夠任意跳轉到應用的某個歷史狀態並進行操做
  • 提供全面的審查和控制功能,讓開發者能夠定製本身的開發工具
  • 將 UI 和業務邏輯分離,使業務邏輯能夠在多個地方重用

另外,對於 React 來講,當遇到如下狀況你或許須要 Redux 的幫助:

  • 同一個 state 須要在多個 Component 中共享
  • 須要操做一些全局性的常駐 Component,好比 Notifications,Tooltips 等
  • 太多 props 須要在組件樹中傳遞,其中大部分只是爲了透傳給子組件
  • 業務太複雜致使 Component 文件太大,能夠考慮將業務邏輯拆出來放到 Reducer 中

4、結語

Redux 是一個爲 JavaScript 應用設計的,可預測的狀態容器。在使用以前,最好先弄清楚他能爲你的程序帶來什麼,須要你作出怎樣的妥協,也就是上文提到的交換方案。但願讀完本文後,你對Redux 的設計思想與使用場景有一個更全面的瞭解。

相關文章
相關標籤/搜索