在開發網站時,有時狀態可能會傳來傳去,不好掌控狀態流,就可能會有 bug,這不是開發者樂見的,還好我們有 Redux 可以幫忙處理這個問題。

什麼是 Redux

Redux 是一個管理狀態的 JavaScript library,一般會跟 React 搭配使用。但其實可以運用在原生的 JavaScript,甚至在其他 JavaScript 框架也能使用。

Redux 核心概念

可以參照下圖所示 ⬇️
Image

  • Redux 的概念是所有 state 是來自建立的 store 統一管理,而 state 是唯讀,能夠確保不會隨意變更。
  • 當某一個元件想要改變 state 時,必須要透過 dispatch 去發送 action。
  • Reducer 是一個 pure function,會帶入 state 和 action,並且回傳一個新的 state,藉由這樣的動作去變異 store 中管理的 state。

實作範例

這篇會透過原生的 JavaScript 來實作一個加減點擊案例。

從 Redux 取出 creatStore,並建立一個 store 變數

1
2
3
const { createStore } = Redux

const store = createStore()

建立預設狀態

1
2
3
const initialState = {
counter: 0
}

建立 reducer

帶入兩個參數,並將 state 指定爲剛剛建立的 initialState ,而 action 則是待會要 dispatch。

邏輯區加入加入 if…else,判斷等一下 dispatch 的 type 是什麼,並且 return 一個物件,最後如果不做處理的話 return 一個原始值:

1
2
3
4
5
6
7
8
9
10
const counterReducer = (state = initialState, action) => {
if (action.type === "plus") {
return {
...state
counter: state.counter + 5
}
}

return state
}

或是寫成 switch,然後寫好加減的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const counterReducer = (state = initialState, action) => {
switch (action.type) {
case 'plus':
return {
...state,
counter: state.counter + action.payload
}
case 'minus':
return {
...state,
counter: state.counter - 5
}
default:
return state
}
}

如果確定要代入的是什麼值的話,可以在 state 給定值,如果不確定或是想要另外做處理,就可以在 action 的 payload 再另外給。

在 store 傳入 reducer

1
const store = createStore(counterReducer)

建立一個 action 來呼叫 reducer

getState() 是 store 中內建的 method,會回傳當下的 state

1
2
3
const counterSubscriber = () => {
const latestState = store.getState()
}

加入一個變異監聽器

使用 store 中內建的 subscribe(),並帶入參數爲剛剛建立的 action

1
store.subscribe(counterSubscriber)

新增 dispatch

觸發 state 變異的唯一方法,帶入 action 參數,並且必須要有 type 屬性,就帶入想要呼叫的 action type 即可,這邊綁定按鈕並監聽事件。

前面的 reducer 中有寫到 action.payload 可以自己帶入,所以這邊 payload 我們帶入想要的值。

1
2
3
4
5
6
7
const plusNumBTN = document.querySelector('.plus-num')

plusNumBTN.addEventListener(
'click',
() => store.dispatch({ type: 'plus', payload: 5 }),
false
)

下方是一個完整的範例,有興趣可以玩看看 ⬇️