前言
一開始我是抱著反正 React 跟 Vue 那麼相似,那~~Redux 跟 Vuex 應該也差不到哪去吧? (到底是哪來的關聯性??)
當我信誓旦旦打開 Redux 官方文件開始閱讀時,發現裡面的每一個單元跟概念都在狠狠地抽我的臉,明明定義看得懂但卻無法理解它背後的含義…
好啦~拋開錯愕的心情準備一起好好認識 Redux 吧!
基本組成架構
Redux 主要是由 Action, Reducer, State 所組成,我會依序介紹以上三者各自的職責再來說明資料流的部分。
Action
Action 是 Store 唯一認證的資料來源,我們可以在 Action 裡定義目標 State 做特定的動作所以必須包含 type
屬性,好讓後續的 Reducer 可以針對該 action.type
來執行特定操作。
上面範例定義了兩個 Action,稍後會在 Component 引入 Action 並把它 Dispatch 到 Reducer。
Reducer
如上述所說的,Reducer 會針對傳進來的 action.type
的值來判斷要做什麼動作修改 state
的呈現。
並且當有多個不同邏輯的 Action 要處理時需要拆分 Reducer 管理,如以下範例:
這部分會有 rootReducer
利用 combineReducers
把不同邏輯的 Reducer import 進來做管理。
接下來我們進一步看 Reducer 到底執行哪些事情~
首先定義 state
初始值,並在宣告的同時將 initialCount
指向給 state
,接著 Reducer 會依傳進來的 action
參數的 type
屬性進行 switch
判斷,最後修改 state
。
State
紀錄狀態值的地方,我們可以利用 store.getState()
取得特定 State。
最後,Redux 有三個原則需要特別注意
Single source of truth
所有的 State 都保存在單一的 State tree,好處是可以讓我們更直觀的 debug 以及閱讀當前 Application state。
State is read-only
Redux 唯一可以更改 State 的方式只有透過 Action 去觸發 Reducer,依賴這種嚴謹的步驟可以讓 State 不輕易被干擾。
Changes are made with pure functions
Reducer 就是 Pure Function,它會接收我們傳進來的 Action 以及前一個 State 的值,並回傳新的 State 做值的修改。
至於 Pure Function 這邊我們只要先知道在 Reducer 只能做可預測的 Sync 事件。setTimeout, fetch API… 這類的 Async 事件我會另外再做說明,因為以上兩者的 Data Flow 有些許的不同。
以上介紹完 Redux 各成員的功能,接著說明 Redux, React 彼此協作有哪些必須先知曉的小常識!
Container & Presentational Component
以下先來個對照表看看兩者有什麼差異~

可以看到 Presentational Component 專注於呈現畫面,並不會直接對 Store 做存取,如果有需要對 Store 做存取就需另外建立 Container Component 以達到關注點分離。
下面展示的範例主要功能是要在畫面上呈現 Count 的值,因為該 Component 會需要跟 Store 連結,所以這邊我將它拆分成 Container, Presentational。
首先,在頂層的 Component 會使用 Provider
將 store
傳遞到下面所有的子元件裡。
接著在 App.js 將按鈕以及需要呈現的畫面的 Component import 進來。
在呈現畫面的 Component 因為需要從 Store 取得 Count,所以這邊建立一個 Container 給它。
當使用 connect() 的同時,該 Component 就可以與 Store 進行聯繫。
通常 connect 比較常用的參數 mapStateToProps, mapDispatchToProps。
使用方式如下:
connect(mapStateToProps, mapDispatchToProps)(PresentationalComponent)
但如果沒有 State 需要傳遞到畫面上,需改成以下做法:
connect(null, mapDispatchToProps)(PresentationalComponent)
所以根據以上範例,在 countStateToProps
把目前的 state
當作參數傳進來並把它指向到 count
回傳到 CountDisplay
這個 Presentational Component。
最後在 CountDisplay 可以接收一個 count
的 props 並將他投遞到畫面上,畫面就會顯示出當前 Count state。
Data Flow
相信剛接觸 Redux 的人或許還會有點不熟悉整個流程,這邊會展示目前為止我使用上的流程,當然也可以參考 官網 的流程圖唷~相信會更清楚了解 Redux 的運作機制!
以上文章或許還有不足之處,如果有哪邊觀念錯誤再麻煩多多指教更正,我會盡快將內容更新 XDD
Reference
https://redux.js.org/tutorials/essentials/part-1-overview-concepts