如何理解Redux的Single Source of Truth理念

最近在首頁上刷到一個問題

Redux數據流管理架構有什麼致命缺陷,未來會如何改進?www.zhihu.com

裏面的一些高贊回答,提到了 Redux 的 Single Source of Truth理念是如何的錯誤。但可惜的是,我認爲他們根本就沒理解對。

本文就完整地闡述如何理解 Redux的 Single Source of Truth 理念


在官方文檔(Three Principles | Redux)中 對 Single source of truth 的整體解釋是這樣的:

37a7e220d0fb3cf1b7fbc4a786d07e4a.jpeg


本地狀態(local state) vs 全局狀態(global state)

文檔的那句話中,最先應該引起讀者注意的是高亮的 global state (全局狀態),即 Single Source of Truth 針對的是 全局狀態

由此馬上該引起我們思考的是——什麼樣的狀態才應該是全局狀態
簡單看看下面幾個例子:

  1. 某個頁面裏 Dialog(對話框)的打開和關閉狀態
  2. 某個頁面裏的表單的內容
  3. 當前路由
  4. 當前web應用的樣式主題的 id
  5. 當前用戶的登錄狀態

個人認爲只有3, 4 和 5 應該是全局狀態,而 1 和 2 都適合存放在本地狀態 —— 判斷邏輯其實很簡單,即 目標狀態是否會關係到 整個APP,是否在大多數頁面/組件中被需要

接着看 3,4 和 5 是否都適合放在 redux store 裏呢?

很明顯 3 是不合適的,因爲 當前路由狀態 理論上就已經存放在 react-dom-router 的 context 中了,完全沒有必要再複製一遍放在 redux store 中 (參考 react-router 的官方文檔 React Router: Declarative Routing for React )

4 和 5 在普通場景下是適合放在 redux 供APP全局使用的。

其實早有開發者提出相關的問題了 —— 如何選擇是在 Redux store 還是 React state 裏存放狀態?(Question: How to choose between Redux's store and React's state? · Issue #1287 · reduxjs/redux)

Redux 的祖師爺 Dan Abrammov 是這麼回答的:

Use React for ephemeral state that doesn't matter to the app globally and doesn't mutate in complex ways. For example, a toggle in some UI element, a form input state. Use Redux for state that matters globally or is mutated in complex ways. For example, cached users, or a post draft.

Sometimes you'll want to move from Redux state to React state (when storing something in Redux gets awkward) or the other way around (when more components need to have access to some state that used to be local).

The rule of thumb is: do whatever is less awkward.




p.s.

根據上述的內容,我們其實已經可以規避使用一些庫了,如 redux-form ,下面的鏈接是 redux-form 和另外兩個主流的 react 表單庫 的 npm 下載量對比,可以說是基本涼涼了

formik vs react redux form vs react hook form | npm trends

a89da0dbf084281246c6c22ab6451570.jpeg

(對React 表單庫有興趣的可以查看我的另一篇文章 FreewheelLee:以React表單庫Formik爲例談優秀的三方庫應該是什麼樣的 )


One Way Data Binding (單向的數據綁定)+ One Way Data Update Approach (單一數據修改途徑)

Single source of truth 不僅僅指單一數據源。

我個人認爲,單向的數據綁定 和 單一數據修改途徑 也是 Redux的Single Source of Truth理念的一部分

關於單向的數據綁定,React 開發者應該都不陌生,因爲這也是 React 的核心理念和最佳實踐。簡單用一個圖闡釋

a611e99bb3fb23f9dfafabf7c770f849.jpeg

單向的數據綁定 就是由聲明好的視圖模板(即React JSX)和 數據模型 生成視圖,而視圖並不會直接影響/改變 數據模型。

(關於理解 單向的數據綁定 ,可以參考 React 官方文檔的 Thinking in React – React )

Redux 也是依照了單向的數據綁定的思想設計的 —— 視圖可以監聽 redux store 的變化而更新視圖,但是不允許視圖直接改變 redux store 裏的數據和狀態。


單一數據修改途徑 這個術語是我自己發明的,想表達的意思就是字面意思 —— 有且只有一種途徑可以更改數據模型。

在 Redux 中,更新 store state 的唯一推薦方式就是 dispatch action,然後經由 middleware 和 reducer 最後生成新的 store state 。

24e198ca74e57bcf0d08e0319d0114d8.png

單一數據修改途徑的設計可以使程序更加可控 —— 既然路只有一條,只需要在這條路上“動手腳”就能影響整個redux數據更新流程,如 打log、修改特定action、添加額外元屬性 等等。

在這個層面而言,這也是一種 single source of truth 。

當你把 單一數據源 + 單一數據綁定 + 單一數據修改途徑 三點聯繫起來理解時,你對 Redux 的設計的領悟是否更加透徹清晰了!



Single store vs Multiple store

Single Source of Truth 的這層內容是比較容易理解的,Redux 採用了與 Flux 不同的設計,只允許一個 Store。

單一Store極大地方便了服務端渲染、debug、檢查(inspect) 等功能。



後記

最後再分享Dan Abramov的一句話:

b389fadf58c13a36c93ce9ef16baca51.jpeg



分享另一個思考

開頭說的那個知乎問題,一些大V的回答獲得了大量的贊同,但事實上內容卻不一定完全正確。在網上瀏覽內容時,要保持自己的獨立思考,不要盲信、盲從,勤於自己搜索調研不要只做伸手黨

推薦我的一篇文章

FreewheelLee:如何閱讀技術博客zhuanlan.zhihu.com

(p.s. 我的專欄、我的文章也可能有錯誤,歡迎讀者指出我的錯誤,共同討論。)



最後,如果覺得我這本文章對你有幫助、有啓發,歡迎 點贊、喜歡、收藏三連!


參考鏈接:

https://en.wikipedia.org/wiki/Single_source_of_truth

https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367

What does the "single source of truth" mean?

Question: How to choose between Redux's store and React's state? · Issue #1287 · reduxjs/redux

Lifting State Up – React


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章