從設計的角度看 Redux

阿里雲最近在作活動,低至2折,有興趣能夠看看:
https://promotion.aliyun.com/...

爲了保證的可讀性,本文采用意譯而非直譯。html

你知道 Redux 真正的做用遠不止狀態管理嗎? 你是否想要了解 Redux 的工做原理? 讓咱們深刻研究 Redux 能夠作什麼,它爲何作它的事情,它的缺點是什麼,以及它與設計有哪些關聯?前端

你據說過 Redux 嗎?它是什麼? 請不要用 Google 搜索react

  • 花哨的後端的東西
  • 我據說過它,但我不知道它是什麼,這多是一個 React 框架
  • 是一種在 React 應用中存儲管理狀態的更好方式

這個問題,我問過 40 多位設計師,以上是他們的經典回答。他們中的許多人都知道 Redux 與React 一塊兒工做,它的工做是狀態管理git

本文的目的就是讓你對 Redux 有更全面的認知: 它能作什麼?爲何它要這樣設計?什麼時候使用它?以及它與設計有哪些關聯?github

個人目標是幫助像大家這樣的設計師。即便您之前沒有寫過一行代碼,我認爲理解 Redux仍然是可能的、有益的和有趣的。redux

什麼是 Redux

在超高水平上,Redux 是開發人員用來簡化他們工做的工具。大家不少人可能都據說過,它的工做是狀態管理。稍後我將解釋狀態管理的含義, 此刻,我只能想讓你看下面這張圖:segmentfault

clipboard.png

爲何要了解 Redux

Redux 更多的是關於應用程序的內部工做而不是它的外觀和感覺。 這是一個有點複雜的工具,學習曲線相對陡峭,但這是否意味着咱們做爲設計師應該遠離它?後端

不。我認爲咱們應該擁抱它。汽車設計師應該瞭解引擎的用途,對嗎?爲了成功地設計應用程序界面,設計師還應該對底層的東西有紮實的瞭解。咱們應該瞭解它能夠作什麼,理解開發人員爲何使用它,並瞭解它的優點和含義。瀏覽器

Redux 能夠作什麼

開發人員在 React 應用中使用 Redux 來管理狀態。這最多見的用法,Redux 改進了React(還沒有)作得很差的方面。前端框架

然而,你很快就會發現 Redux 的真正功能遠遠不止於此,讓咱們從瞭解狀態管理的真正含義開始。

狀態管理

若是你不肯定這個狀態意味着什麼,讓咱們用一個更通用的術語來替換它:數據。狀態是不斷變化的數據,狀態決定在用戶界面上顯示什麼。

狀態管理是什麼意思? 通常來講,咱們須要在應用程序中管理三個方面的數據

  1. 獲取和存儲數據
  2. 將數據綁定到 UI 元素
  3. 改變數據

好比咱們要作一個 Dribbble 的做品頁面。在做業頁面上咱們想要展現的數據有哪些?其中包括做者的頭像照片、名稱、動態 GIF 圖片、點贊數量、評論,以及等等。

clipboard.png

首先,咱們須要從雲服務器獲取全部這些數據並將其放在某個位置。接下來,咱們須要實際顯示數據。咱們須要將這些數據分配給對應的 UI 元素,這些 UI 元素表示咱們在瀏覽器中實際看到的內容。例如,咱們將頭像照片的 URL 分配給 img 標籤的 src 屬性:

<img src='https://url/to/profile_photo'>

最後,咱們須要處理對數據的更改。例如,若是用戶向Dribbble shot添加評論或點贊,咱們須要更新相應的 HTML。

協調狀態的這三個方面是前端開發的重要組成部分,React 對這項任務有不一樣程度的支持。有時候 React 中的內置功能運行得足夠好。但隨着應用程序變得愈來愈複雜,僅憑React 可能會更難管理它的狀態。這就是爲何許多人開始使用Redux做爲替代。

獲取和存儲數據

在React中,咱們將UI分解爲組件。這些組件均可以分解爲更小的組件。

圖片描述

若是咱們的 UI 是這樣構造的,那麼在填充UI以前,咱們何時獲取數據以及在哪裏存儲數據

假設每一個組件中都有一個廚師。從服務器獲取數據就比如是採購所需的全部原材料以準備佳餚。

一種簡單的方法是在須要的地方和時間獲取和存儲數據。這就像每一個廚師直接從遙遠的農場購買蔬菜和肉類同樣。

簡單方式: 每一個組件各自獲取本身所須要的數據

這種方法是很浪費的。即便對於相同的數據,咱們也須要從多個組件屢次請求服務器。廚師會浪費大量的汽油和時間來回奔波。

使用Redux,咱們只獲取一次數據並將其存儲在一箇中心位置,稱爲 store。而後,任何組件均可以隨時使用這些數據。這就像附近有一家超市,咱們的廚師能夠在那裏買到全部的食材。這家超市派卡車從農場大批運回蔬菜和肉類。這比讓個別廚師親自去農場效率高得多。

store 仍是惟一的數據源。組件一般從 store 中獲取數據,而不是其餘地方。這使得 UI 保持高度統一。

Redux 將數據集中地存儲起來,並將數據分配給 UI 元素

將數據綁定到 UI 元素

若是單單使用 React 的話,實際上有一種更好的方法來獲取和存儲數據。咱們能夠請咱們很是善良的廚師Shotwell爲他全部的廚師朋友購物。他會開一輛卡車去農場,把貨物運回。咱們能夠從容器組件中獲取數據,例如 Dribbble 示例中的 Shot 組件,並將其用做單一的數據來源。

從根組件獲取數據

這種方法比從每一個組件獲取數據的簡單方法更有效。可是 Shotwell 是如何將配料傳遞給其餘廚師的呢? 如何將數據傳遞給實際渲染 HTML 元素的組件? 咱們將數據從外部組件傳遞到內部組件,就像接力棒同樣,一直傳遞到數據到達目的地。

例如,做者頭像的 URL 須要從 Shot 傳遞到ShotDetailTitle,最後傳遞到<img> 標籤。若是咱們的廚師住在公寓裏,它看起來就像這樣:

經過 props 將數據傳遞給目標組件

要將數據交付到目的地,咱們必須使用路徑上的全部組件,即便它們根本不須要數據。若是有不少層的話,那就太煩人了。

若是超市能送貨上門呢? 使用 Redux,咱們能夠將任何數據插入任何組件,而不影響其餘組件,就像這樣

更準確地說,其實是另外一個叫作 react-redux 的庫將數據提供給組件的,而並不是 Redux 自己。但由於 react-redux 自己只是個鏈接庫,而且開發者一般一塊兒使用 Redux 和 react-redux ,所以我認爲將它當作是 Redux 的好處之一是並沒有不妥。

使用 Redux 將數據直接提取至目標組件

注意:在React(16.3)的最新版本中,有一個新的 context API,它的提取數據功能幾乎與 Redux 是相同的。所以,若是你的團隊使用 Redux 的惟一緣由是爲了提取數據,不妨認真考慮升級到 React 16.3!

改變數據

有時候,在應用程序中更新數據的邏輯可能至關複雜。它可能涉及多個相互依賴的步驟。在更新應用程序狀態以前,可能須要等待多個服務器的響應。咱們可能須要在不一樣的時間、不一樣的條件下更新多處 state 的狀態。

若是咱們沒有一個適合全部邏輯的良好結構,很容易讓人使人不知所措,代碼也很難理解和維護。

Redux 讓咱們分而治之。 它提供了一種將數據更新邏輯分解爲小「reducer」的標準方法。 這些 reducer 和諧地協同工做以完成複雜的動做。

將複雜邏輯拆分紅 reducer

Redux 的真正威力

到目前爲止,Redux 看上去只是 React 的輔助工具。開發者使用它來解決 React 的某些痛點。但 React 正在快速着手解決這些問題!事實上,Redux 的做者 Dan Abramov 在幾年前已經加盟 Facebook 的 React 核心團隊。他們一直致力於提高 React 的開發體驗: context API (16.3版本發佈)、更好的數據獲取 API (詳情請見 Dan Abramov 於2018年2月的演講)、更好的 setState API,等等。

它會使 Redux 過期嗎?

你猜怎麼着? 我尚未向你展現Redux的真正力量!

Redux 的威力遠不止狀態管理

Redux 迫使開發人員遵循一些嚴格的規則,這給 Redux 帶來了強大的功能。

  1. 全部數據(應用程序狀態)必須以明文形式描述。 你應該可以用筆在紙上寫下全部數據。
  2. 每個動做(數據的變動)都必須用清晰的文字來描述。你必須把你要作的事寫下來,而後再作改變。你不能改變數據而不留下痕跡。在 Redux 的術語中這稱之爲 「派發 (dispatching) 動做」
  3. 更改數據的代碼必須像數學公式同樣。 在相同輸入的狀況下,它必須返回相同的結果。 不管你運行多少次,4 的平方老是 16。

當你遵循上述原則來開發應用的話,難以想象的事情就來了。Redux 將開啓許多很酷的特性,這些特性使用其餘技術很難實現,或者實現起來成本很高。下面是一些例子。

我從 Dan Abramov 文章 「You Might Not Need Redux」 和 「React Beginner Question Thread.」 中收集了一些示例。

撤銷、重作

流行的 撤銷/重作 功能須要系統級規劃。由於撤銷/重作須要記錄和回放應用程序中的每一次數據更改,因此你必須從一開始就在架構中考慮到這一點。若是是過後纔想到的,那就須要修改不少文件,這是無數錯誤的根源。

撤消、重作

正由於 Redux 須要每一個動做都以文本的形式進行描述,因此能夠說是天生就支持撤消/重作。這個文檔中介紹瞭如何使用 Redux 來實現撤消/重作。

協做環境

若是你要構建相似於 Google Docs 的應用,其中多個用戶在複雜任務上協同工做,請考慮使用 Redux。 它可以爲你完成大量繁重的工做。。

Google Docs

Redux 能夠很是輕鬆地經過網絡發送正在發生的事情。 接收另外一個用戶在另外一臺機器上執行的操做,重放更改並與本地發生的操做合併是很簡單的。

OPTIMISTIC UI

Optimistic UI 是 Meteor 提出來的一種前端界面快速響應用戶交互的概念,以前叫 Latency Compensation,主要做用是在客戶端直接響應用戶的交互,而不用等信息從客戶端發送到服務器,完成更新確認,再從服務器返回客戶端這一個來回完成後再作響應。有點相似遊戲領域裏的 Dead Reckoning,在客戶端離線對用戶行爲進行推測,達到隱藏延時和減小帶寬使用的技術。

Optimistic UI

舉一個簡單的例子,在Twitter應用程序中,你的點贊它須要請求服務器進行一些檢查,例如,該推文是否仍然存在。 Optimistic UI 的作法不是傳統的轉圈等待幾秒,而後顯示結果,而是選擇欺騙用戶!它事先假定全部請求都是成功的,當用戶點贊時直接+1。

clipboard.png

這種方式有效的緣由在於大多數時候請求都是正常的。當請求失敗是,應用只需回滾至前一個 UI 狀態便可,並使用服務器響應的實際結果,例如顯示錯誤信息。

如同撤消/重作同樣,Redux 也支持 Optimistic UI。 當從服務器收到否認結果時,能夠輕鬆記錄,重放和還原數據更改。

持久化和從狀態啓動

Redux 能夠很容易地將應用程序中發生的事情保存到本地存儲中。以後,即便電腦重啓,應用程序也能夠加載全部數據,並從徹底相同的位置繼續運行,就像從未中斷過同樣。

保存/加載遊戲進度

若是你使用 Redux 構建遊戲,則只須要幾行代碼來保存/加載遊戲進度,而無需更改其他代碼。

真正可擴展的系統

使用 Redux,你必須「dispatch」一個 action 來更新應用程序中的任何數據。 這種限制使咱們能夠深刻了解應用程序中發生的各個方面。

你能夠構建真正可擴展的應用,其中每一個功能均可以由用戶來自定義。例如,參考 Hyper ,這是一個使用 Redux 開發的終端應用。「hyperpower」 插件增長了光標的閃光點,並可使窗口抖動。你是否喜歡這種 「wow」 模式呢?(或許這功能並無什麼用,但倒是足夠吸人眼球)

圖片描述

時程調試(TIME-TRAVEL DEBUGGING)

當調試應用時可以進行時間旅行會是怎樣一種體驗?運行應用的過程當中,隨意倒退或前進幾回以找到 bug 發生的確切位置,修復 bug 後重放以確認是否修復。

Redux 讓開發者夢想成真。Redux 開發者工具可使開發者經過拖拽滑動條來操縱應用的進度,就像 Youtube 視頻通常。

它是如何工做的? 還記得 Redux 強制執行的三條嚴格規則嗎? 這是它的祕訣所在。

圖片描述

自動錯誤報告

想象一下:一個用戶在你的應用程序中發現了一些錯誤,想要報告這個 bug。她煞費苦心地回憶和描述她所作的事情。而後,開發人員嘗試手動執行這些步驟,以查看是否再次發生錯誤。錯誤報告多是模糊的或不許確的。開發人員很難找到 bug 所在的位置。

如今,這個怎麼樣。 用戶單擊「報告錯誤」按鈕。 系統自動將她所作的事情發送給開發人員。 開發人員單擊「重播錯誤」按鈕並觀察錯誤是如何發生的。 bug 被當場壓扁,每一個人都很開心!

Redux Bug Reporter 就是這樣玩的。它的工做原理呢?Redux 的限制條件讓一切變成可能。

自動反饋 Bug

Redux 的缺點

Redux 執行的三個主要規則是一把雙刃劍。它們支持強大的功能,但同時也帶來不可避免的缺點。

陡峭的學習曲線

Redux 的學習曲線比較陡峭。 理解,記憶並習慣其模式須要時間。 若是你徹底不會 Redux 和 React ,不推薦你二者同時學習。

 「樣板」 代碼

在許多狀況下,使用Redux意味着編寫更多代碼。一般須要接觸多個文件才能使一個簡單的功能正常工做。人們一直在抱怨他們必須用 Redux 編寫的樣板代碼。

我知道,這聽起來很矛盾。 我不是說 Redux 可以用最少的代碼實現功能嗎? 這有點像使用洗碗機。 首先,你得花時間仔細地排列盤子。 在此以前,你將看到洗碗機的好處:節省實際清潔餐具的時間,消毒餐具等。你必須決定準備時間是否值得!

性能損耗

因爲其強制執行的限制,Redux 也可能對性能產生影響。 每當數據發生變化時,它會增長一點開銷。 在大多數狀況下,這不是什麼大問題,並且放緩並不明顯。 仍然,當存儲中存在大量數據而且當數據頻繁改變時(例如,當用戶在移動設備上快速鍵入時),UI 可能所以變得緩慢。

Redux 不僅是爲 React 而生

一個常見的誤解是 Redux 僅用於 React。 聽起來Redux在沒有React的狀況下沒法作任何事情。 事實上,正如咱們以前所討論的,Redux在幾個重要方面補充了React。 React 是最最多見的 Redux 用例。

然而,事實上,Redux可使用任何前端框架,如Angular、Ember.js 甚至jQuery 或者 普通的JavaScript。試着谷歌一下,你會發現這個,這個,這個甚至這個。Redux 的通常思想適用於任何地方

只要你明智地使用 Redux,你能夠在不少狀況下獲得它的好處,而不只僅是在React應用中。

Redux 能夠搭配其餘前端框架一塊兒使用

總結

有不可避免的缺點。一個開發團隊的職責就是進行評估,看如何進行取捨並做出明智的選擇。

做爲設計師,若是咱們瞭解Redux的優點和劣勢,咱們將可以從設計的角度爲這一決策作出貢獻。 例如,咱們是否能夠設計用戶界面以減輕潛在的性能影響? 也許咱們能夠提倡包含撤消/重作功能來刪除大量的確認對話框? ?或許咱們能夠提倡 optimistic UI ,由於它可以以相對較低的代價來提高用戶體驗。

你的點贊是我持續分享好東西的動力,歡迎點贊!

交流

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

https://github.com/qq44924588...

我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!

關注公衆號,後臺回覆福利,便可看到福利,你懂的。

clipboard.png

相關文章
相關標籤/搜索