本系列文章主要整理於書籍《React狀態管理與同構實戰》。
本文推薦讀者:菜鳥前端,初學前端者。
本文是對書籍的又一層整理,內容是在本人理解之後再次簡略,相當於在前人咀嚼之後再咀嚼了,加之本人才疏學淺,
可能會(很大機率會)有一些描述不當的地方,希望同行前輩多多指正。
複製程式碼
一、Redux應用架構基礎
1、Redux是什麼
React應用由元件構成其骨架,而狀態 state 就是溝通骨架的血液。當專案越來越大時,元件之間的通訊會變得更為頻繁,此時元件之間的狀態會變得更為複雜,這個時候需要有一種技術來對狀態進行管理,而Redux就是這樣的一種管理通訊狀態的技術。
1.1 Redux是庫結合模式
- 按照官方定義
Redux is a predictable state container for Javascript apps
,Redux
是一個在JS中可以預測狀態的容器。 - Redux 是一個庫,同時它規定了開發者開發的方方面面,所以又像是一種設計模式,所以稱
Redux
是一個 嚴格規定了使用模式的庫 - 作用:Redux 採用函數語言程式設計思想,採用了單向資料流的理念,專注於全域性狀態的管理,為實現對資料狀態的管理封裝了很多方法,並且規定了我們管理的模式(如何管理,怎樣管理)
1.2 React 與 Redux 之間的關係
- 它們之間沒有必然聯絡。
- 但是當 React 專案越來越大時,對狀態的關注與管理要求越來越高;而 Redux 能夠 ”規範化“狀態的改變,隱藏二者經常一同使用。
2、 Redux的設計哲學
2.1 Single source of truth
-
我們使用有且僅有的一個物件作為表述整個狀態機的全部狀態,並儲存在 store 中,這個 store 就 React 元件以來的 “Single soure of truth”。
-
整個頁面狀態資料樹被儲存在一個物件中,會隨著資料的變更而發生變化,任何時候我們都可以同過一下方法獲取到資料狀態:
let state = store.getState()
複製程式碼
這樣做的好處?
- 可以讓我們聚焦於對這個物件的使用
- 頁面的展示內容依賴於各個元件的狀態資料
- 各個元件的狀態資料依賴於一個儲存在 store 中 JS 物件
- 這個物件可以通過
store.getState()
獲取
2.2 State is only read
- 頁面狀態資料書返回的結果是隻讀的
- 當我們需要新的資料狀態時,會生成一個全新的狀態資料樹,使得 store.getState() 返回一個全新的物件。
- 這個生成新的狀態資料樹的過程如下:
- 當資料需要更新的時候, dispatch (派發)出一個 action(動作/事件)
- action 是一個JS物件,是用來描述這個動作單元變化的所有資訊。
- Redux 會根據派發的資訊進行一定的操作進而生產一個新的狀態資料樹
2.3 Changes are made with pure functions called reducer
當我們想要更改頁面時,我們想到的是更改頁面狀態資料樹中的狀態,而狀態資料樹返回的物件是隻讀的,只能同 dispatch 派發出 action ,然後根據一些操作得到新的狀態資料樹,進而改變頁面。
那麼派發了 action 之後, Redux 的後續操作是如何建立出新的狀態資料樹呢?
- 使用
reducer
函式接受 action ,然後執行狀態資料樹的變更。經過 reducer 函式處理之後, store.getState() 方法會返回新的狀態資料樹 - reducer 函式將根據原始狀態資料樹,結合描述改變資訊 action ,生產一個新的頁面狀態資料樹,並把它應用在 store.getState 中
對於 reducer 函式而言:
- Reducer 函式有兩個引數,一個是傳入的狀態 preState,另外一個是描述改變資訊的 action,返回的是一個新的狀態 newState。
小結:
-
Redux追求單一資料來源,所有狀態都儲存在 store當中,是一個物件。
-
狀態資料是隻讀的,當頁面需要作出改變的時候,這個改變由 action 進行描述,並由 dispatch 方法進行派發。
-
這個 action 被響應的 reducer 作為引數獲取,並根據現有的頁面狀態資料樹生產一個新的狀態資料樹。
-
結合 React, 當頁面中各個 React 元件根據新的頁面狀態資料樹抽取出自己需要的狀態進行更新,並觸發渲染後,就會得到我們預期的新的頁面。
3、 函數語言程式設計和純函式
- 函數語言程式設計是一種典型的宣告式程式設計,與指令式程式設計相對立,它更看重的是執行的目的而不是執行過程。
- 函式可以與其它資料一樣,作為引數傳遞,或者作為返回值返回,這體現了函式是 “第一公民”。
為什麼 redux 會遵循函數語言程式設計的理念,這樣做有什麼好處?
設想場景:當我們發現程式中存在一個bug,頁面需要展示的是資料A,而我們現在展示的是資料B
-
出現的 state 是在 reducer 中產生的
-
產生這個state 是由於 reducer 接收了 action 這個描述狀態改變的資訊。
-
所以現在要看是 action 描述錯誤了,還是對應的 reducer 函式出現錯誤
-
而這就是 Redux 所擁有的可預測性,可追溯性——可以使得除錯和維護程式碼更加簡單。