阿里雲最近在作活動,低至2折,有興趣能夠看看:
https://promotion.aliyun.com/...
爲了保證的可讀性,本文采用意譯而非直譯。html
你知道 Redux 真正的做用遠不止狀態管理嗎? 你是否想要了解 Redux
的工做原理? 讓咱們深刻研究 Redux
能夠作什麼,它爲何作它的事情,它的缺點是什麼,以及它與設計有哪些關聯?前端
你據說過 Redux
嗎?它是什麼? 請不要用 Google 搜索react
這個問題,我問過 40 多位設計師,以上是他們的經典回答。他們中的許多人都知道 Redux 與React 一塊兒工做,它的工做是狀態管理。git
本文的目的就是讓你對 Redux 有更全面的認知: 它能作什麼?爲何它要這樣設計?什麼時候使用它?以及它與設計有哪些關聯?github
個人目標是幫助像大家這樣的設計師。即便您之前沒有寫過一行代碼,我認爲理解 Redux仍然是可能的、有益的和有趣的。redux
在超高水平上,Redux 是開發人員用來簡化他們工做的工具。大家不少人可能都據說過,它的工做是狀態管理。稍後我將解釋狀態管理的含義, 此刻,我只能想讓你看下面這張圖:segmentfault
Redux 更多的是關於應用程序的內部工做而不是它的外觀和感覺。 這是一個有點複雜的工具,學習曲線相對陡峭,但這是否意味着咱們做爲設計師應該遠離它?後端
不。我認爲咱們應該擁抱它。汽車設計師應該瞭解引擎的用途,對嗎?爲了成功地設計應用程序界面,設計師還應該對底層的東西有紮實的瞭解。咱們應該瞭解它能夠作什麼,理解開發人員爲何使用它,並瞭解它的優點和含義。瀏覽器
開發人員在 React 應用中使用 Redux 來管理狀態。這最多見的用法,Redux 改進了React(還沒有)作得很差的方面。前端框架
然而,你很快就會發現 Redux 的真正功能遠遠不止於此,讓咱們從瞭解狀態管理的真正含義開始。
若是你不肯定這個狀態意味着什麼,讓咱們用一個更通用的術語來替換它:數據。狀態是不斷變化的數據,狀態決定在用戶界面上顯示什麼。
狀態管理是什麼意思? 通常來講,咱們須要在應用程序中管理三個方面的數據
好比咱們要作一個 Dribbble 的做品頁面。在做業頁面上咱們想要展現的數據有哪些?其中包括做者的頭像照片、名稱、動態 GIF 圖片、點贊數量、評論,以及等等。
首先,咱們須要從雲服務器獲取全部這些數據並將其放在某個位置。接下來,咱們須要實際顯示數據。咱們須要將這些數據分配給對應的 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 保持高度統一。
若是單單使用 React 的話,實際上有一種更好的方法來獲取和存儲數據。咱們能夠請咱們很是善良的廚師Shotwell爲他全部的廚師朋友購物。他會開一輛卡車去農場,把貨物運回。咱們能夠從容器組件中獲取數據,例如 Dribbble 示例中的 Shot
組件,並將其用做單一的數據來源。
這種方法比從每一個組件獲取數據的簡單方法更有效。可是 Shotwell 是如何將配料傳遞給其餘廚師的呢? 如何將數據傳遞給實際渲染 HTML 元素的組件? 咱們將數據從外部組件傳遞到內部組件,就像接力棒同樣,一直傳遞到數據到達目的地。
例如,做者頭像的 URL 須要從 Shot
傳遞到ShotDetail
、Title
,最後傳遞到<img>
標籤。若是咱們的廚師住在公寓裏,它看起來就像這樣:
要將數據交付到目的地,咱們必須使用路徑上的全部組件,即便它們根本不須要數據。若是有不少層的話,那就太煩人了。
若是超市能送貨上門呢? 使用 Redux
,咱們能夠將任何數據插入任何組件,而不影響其餘組件,就像這樣
更準確地說,其實是另外一個叫作 react-redux 的庫將數據提供給組件的,而並不是 Redux 自己。但由於 react-redux 自己只是個鏈接庫,而且開發者一般一塊兒使用 Redux 和 react-redux ,所以我認爲將它當作是 Redux 的好處之一是並沒有不妥。
注意:在React(16.3)的最新版本中,有一個新的
context
API,它的提取數據功能幾乎與 Redux 是相同的。所以,若是你的團隊使用 Redux 的惟一緣由是爲了提取數據,不妨認真考慮升級到 React 16.3!
有時候,在應用程序中更新數據的邏輯可能至關複雜。它可能涉及多個相互依賴的步驟。在更新應用程序狀態以前,可能須要等待多個服務器的響應。咱們可能須要在不一樣的時間、不一樣的條件下更新多處 state
的狀態。
若是咱們沒有一個適合全部邏輯的良好結構,很容易讓人使人不知所措,代碼也很難理解和維護。
Redux 讓咱們分而治之。 它提供了一種將數據更新邏輯分解爲小「reducer」的標準方法。 這些 reducer 和諧地協同工做以完成複雜的動做。
到目前爲止,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 將開啓許多很酷的特性,這些特性使用其餘技術很難實現,或者實現起來成本很高。下面是一些例子。
我從 Dan Abramov 文章 「You Might Not Need Redux」 和 「React Beginner Question Thread.」 中收集了一些示例。
流行的 撤銷/重作 功能須要系統級規劃。由於撤銷/重作須要記錄和回放應用程序中的每一次數據更改,因此你必須從一開始就在架構中考慮到這一點。若是是過後纔想到的,那就須要修改不少文件,這是無數錯誤的根源。
正由於 Redux 須要每一個動做都以文本的形式進行描述,因此能夠說是天生就支持撤消/重作。這個文檔中介紹瞭如何使用 Redux 來實現撤消/重作。
若是你要構建相似於 Google Docs 的應用,其中多個用戶在複雜任務上協同工做,請考慮使用 Redux。 它可以爲你完成大量繁重的工做。。
Redux 能夠很是輕鬆地經過網絡發送正在發生的事情。 接收另外一個用戶在另外一臺機器上執行的操做,重放更改並與本地發生的操做合併是很簡單的。
Optimistic UI 是 Meteor 提出來的一種前端界面快速響應用戶交互的概念,以前叫 Latency Compensation,主要做用是在客戶端直接響應用戶的交互,而不用等信息從客戶端發送到服務器,完成更新確認,再從服務器返回客戶端這一個來回完成後再作響應。有點相似遊戲領域裏的 Dead Reckoning,在客戶端離線對用戶行爲進行推測,達到隱藏延時和減小帶寬使用的技術。
舉一個簡單的例子,在Twitter應用程序中,你的點贊它須要請求服務器進行一些檢查,例如,該推文是否仍然存在。 Optimistic UI 的作法不是傳統的轉圈等待幾秒,而後顯示結果,而是選擇欺騙用戶!它事先假定全部請求都是成功的,當用戶點贊時直接+1。
這種方式有效的緣由在於大多數時候請求都是正常的。當請求失敗是,應用只需回滾至前一個 UI 狀態便可,並使用服務器響應的實際結果,例如顯示錯誤信息。
如同撤消/重作同樣,Redux 也支持 Optimistic UI。 當從服務器收到否認結果時,能夠輕鬆記錄,重放和還原數據更改。
Redux 能夠很容易地將應用程序中發生的事情保存到本地存儲中。以後,即便電腦重啓,應用程序也能夠加載全部數據,並從徹底相同的位置繼續運行,就像從未中斷過同樣。
若是你使用 Redux 構建遊戲,則只須要幾行代碼來保存/加載遊戲進度,而無需更改其他代碼。
使用 Redux,你必須「dispatch」一個 action
來更新應用程序中的任何數據。 這種限制使咱們能夠深刻了解應用程序中發生的各個方面。
你能夠構建真正可擴展的應用,其中每一個功能均可以由用戶來自定義。例如,參考 Hyper ,這是一個使用 Redux 開發的終端應用。「hyperpower」 插件增長了光標的閃光點,並可使窗口抖動。你是否喜歡這種 「wow」 模式呢?(或許這功能並無什麼用,但倒是足夠吸人眼球)
圖片描述
當調試應用時可以進行時間旅行會是怎樣一種體驗?運行應用的過程當中,隨意倒退或前進幾回以找到 bug 發生的確切位置,修復 bug 後重放以確認是否修復。
Redux 讓開發者夢想成真。Redux 開發者工具可使開發者經過拖拽滑動條來操縱應用的進度,就像 Youtube 視頻通常。
它是如何工做的? 還記得 Redux 強制執行的三條嚴格規則嗎? 這是它的祕訣所在。
圖片描述
想象一下:一個用戶在你的應用程序中發現了一些錯誤,想要報告這個 bug。她煞費苦心地回憶和描述她所作的事情。而後,開發人員嘗試手動執行這些步驟,以查看是否再次發生錯誤。錯誤報告多是模糊的或不許確的。開發人員很難找到 bug 所在的位置。
如今,這個怎麼樣。 用戶單擊「報告錯誤」按鈕。 系統自動將她所作的事情發送給開發人員。 開發人員單擊「重播錯誤」按鈕並觀察錯誤是如何發生的。 bug 被當場壓扁,每一個人都很開心!
Redux Bug Reporter 就是這樣玩的。它的工做原理呢?Redux 的限制條件讓一切變成可能。
Redux 執行的三個主要規則是一把雙刃劍。它們支持強大的功能,但同時也帶來不可避免的缺點。
Redux 的學習曲線比較陡峭。 理解,記憶並習慣其模式須要時間。 若是你徹底不會 Redux 和 React ,不推薦你二者同時學習。
在許多狀況下,使用Redux意味着編寫更多代碼。一般須要接觸多個文件才能使一個簡單的功能正常工做。人們一直在抱怨他們必須用 Redux 編寫的樣板代碼。
我知道,這聽起來很矛盾。 我不是說 Redux 可以用最少的代碼實現功能嗎? 這有點像使用洗碗機。 首先,你得花時間仔細地排列盤子。 在此以前,你將看到洗碗機的好處:節省實際清潔餐具的時間,消毒餐具等。你必須決定準備時間是否值得!
因爲其強制執行的限制,Redux 也可能對性能產生影響。 每當數據發生變化時,它會增長一點開銷。 在大多數狀況下,這不是什麼大問題,並且放緩並不明顯。 仍然,當存儲中存在大量數據而且當數據頻繁改變時(例如,當用戶在移動設備上快速鍵入時),UI 可能所以變得緩慢。
一個常見的誤解是 Redux 僅用於 React。 聽起來Redux在沒有React的狀況下沒法作任何事情。 事實上,正如咱們以前所討論的,Redux在幾個重要方面補充了React。 React 是最最多見的 Redux 用例。
然而,事實上,Redux可使用任何前端框架,如Angular、Ember.js 甚至jQuery 或者 普通的JavaScript。試着谷歌一下,你會發現這個,這個,這個甚至這個。Redux 的通常思想適用於任何地方
只要你明智地使用 Redux,你能夠在不少狀況下獲得它的好處,而不只僅是在React應用中。
有不可避免的缺點。一個開發團隊的職責就是進行評估,看如何進行取捨並做出明智的選擇。
做爲設計師,若是咱們瞭解Redux的優點和劣勢,咱們將可以從設計的角度爲這一決策作出貢獻。 例如,咱們是否能夠設計用戶界面以減輕潛在的性能影響? 也許咱們能夠提倡包含撤消/重作功能來刪除大量的確認對話框? ?或許咱們能夠提倡 optimistic UI ,由於它可以以相對較低的代價來提高用戶體驗。
你的點贊是我持續分享好東西的動力,歡迎點贊!
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq44924588...
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。