Redux 簡介(上) — 使用 Redux 實作存錢筒功能

谷哥
5 min readDec 10, 2019
Redux

在 SPA 的世界裡,前端的操作介面與邏輯趨於複雜,因此發展出各式各樣的前端渲染引擎或是框架 (例如 React、Vue、Angular 等等),前端開發者只需注重在資料層,畫面的渲染則交由引擎或是框架來處理,大幅提升 DX (Developer Experience),當然前端開發者也能花更多的時間來處理畫面互動,進而提升 UX (User Experience)。

不過隨著功能變得越來越多甚至越來越複雜,前端需要暫存更多的資料 (或狀態),而這些資料會散落在不同的頁面或是元件中,有時候就會遇到多個頁面或是元件需要共用同一份資料。

左邊選單、中間文字輸入框、導覽列右方都需要顯示我的大頭照

一旦修改其中一份資料,就要確保其他地方的資料同步更新,避免畫面不一致的情況產生而影響使用者體驗,而為了保持資料的一致性,開發者需要加入許多同步資料的邏輯在程式碼中,造成資料更新的來源增加,遇到 bug 就會難以 trace code。

我們何不將所有元件的資料全部集中存放在一起,當元件需要用到某些資料時再從那裡取得呢?

https://note.pcwu.net/2017/03/04/redux-intro/

Redux 簡介

Redux 讓開發者可以在 JavaScript 應用程式建立一個而且唯一的資料管理容器,用來集中式的管理資料,這個資料管理容器又稱為 Store (倉庫),主要由 State、Action、Reducer 組成,讓我們先來暸解它們在 Redux 的架構中分別扮演的角色以及彼此之間的關係。

State

用來儲存整個應用程式的資料,由一個單一的 Object Tree 構成,以遵循 Single Source of Truth 原則。

透過 store.getState() 來取得 State。

Action

要改變 State 唯一的方式就是指派一個 Action,而 Action 本身就只是一個 Object,但 Action 不會直接修改 State,而是交由 Reducer 來處理。

透過 store.dispatch() 來指派 Action。

Reducer

Reducer 是一個 Pure Function,能夠取得當前的 State 和被指派的 Action,並且回傳一個新的 State。

https://jonny-huang.github.io/angular/training/31_ngrx_1/

使用 Redux 實作存錢筒功能

存錢筒具有一個狀態,也就是存錢筒內的金額,以下使用 Redux 來模擬存錢筒,管理存錢筒內的金額。

定義 Action

首先設定存錢筒具有「可以存入任意金額的錢」以及「全部一次提領出來」兩種功能,分別對應 typeDEPOSITWITHDRAW 的兩種 Action:

// 存錢的 Action,存入的金額為 amount 
{
type: 'DEPOSIT',
amount: 100
}
// 領錢的 Action,全部一次提領出來所以不需要 amount
{
type: 'WITHDRAW_ALL'
}

定義 Reducer

Reducer 設定第一個 state 參數的預設參數為 0,當作存錢筒內的初始金額,並且根據第二個 action 參數的 type 作出相對應的處理:

function reducer(state = 0, action) {
switch(action.type) {

// 如果 type 為 'DEPOSIT',回傳當前的金額加上存入的金額
case 'DEPOSIT':
return state + action.mount

// 如果 type 為 'WITHDRAW',回傳 0
case 'WITHDRAW':
return 0

// 如果 type 為其他,回傳當前的金額
default:
return state
}
}

建立 Store

透過 createStore 將定義好的 Reducer 傳入作為第一個參數來建立 Store:

const store = createStore(reducer)

模擬存入任意金額的錢

store.getState() // 一開始為 0 塊錢// 存入 10 塊錢
store.dispatch({
type: 'DEPOSIT',
amount: 10
})
store.getState() // 現在有 10 塊錢// 再存入 100 塊錢
store.dispatch({
type: 'DEPOSIT',
amount: 100
})
store.getState() // 現在總共有 110 塊錢

模擬將全部的錢一次提領出來

// 全部提領出來
store.dispatch({
type: 'WITHDRAW'
})
store.getState() // 0 塊錢

React 與 Redux

從以上例子中可以看到,Redux 是一個可以獨立運作的套件,除此之外 Redux 也能搭配各種不同的前端框架,其中最常見的即是 React。

Redux 官方提供了另外一套 React-Redux 套件來整合 React 和 Redux,幫助開發者更容易的處理 React UI 和 Redux Data 的互動,會在下篇文章中和各位來分享。

--

--