pcwu's TIL Notes


[Redux] Redex 核心概念筆記

Flux 為 Facebook 提出的一個架構,用以方便管理 React 錯綜複雜的 state 及 action 關係。而 Redux 大幅簡化了 Flux 的概念。

要學習 Redux 強烈建議透過原作者的影片:https://egghead.io/lessons/javascript-redux-the-single-immutable-state-tree

Redux 三大元件和三大原則:

三大元件:

三大原則:

Redux 運作流程

(圖片來源)

以上的圖片就是一個簡單的流程:

  1. 事件發生: 例如使用者點擊某元件 onclick
  2. 發送 action: Action Creator 向 Store 發送 action
  3. 更改 state: Store 調用 Reducer ,給予 state 和 action 而得到新的 state。
  4. 發佈通知: 需要用到 state 的元件會向 store 訂閱通知,一但 state 有變化,即會收到通知,可重新取得所需 state,重新渲染元件。

Redux 三大元件

以下用最簡單的計數器為例子來簡單介紹三大元件:

Action

Action 就是一個物件,描述發生的事件類別(type),以及所承載的資訊(payload)。

以計數器這個例子來說,action 只要提供 type 就有足夠的資訊了,不需要另外有 payload。

{
  type: 'INCREMENT'
}

但如果是像是 TODO List,可能的 action 會長這樣:

{
  type: ADD_TODO,
  payload: {
    text: 'Buy Milk'
  }
}

Reducer

根據剛剛的定義,reducer是一個 pure function,負責將給定的 state 根據給定的 action 做變化而得到新的 state。也就是:

(previousState, action) => newState

所以透過給定的 state 跟 action ,可以得到新的 state。 Redux 為了讓事情單純,且可以回溯狀態,所以嚴格規定 reducer 是不能有副作用的 pure function,以確保給定相同的 state 和 action 會永遠得到相同的新 state。

以下為一個簡單 reducer 的例子。 reducer 固定引進 state 和 action 2 個變數。以這個例子來說,state 為一個數字,記錄目前計數器的值, action 則有「加」和「減」2種可能。

const counter = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
}

Store

Redux 的 store 主要就是所謂的 store tree,集中管理了整個 app 的狀態資訊。整個 Redux 就是以 store 為核心來運作,所以 store 只會且只能有一個,而且所有東西都會被包在裡面(reducermiddleware等等)

store 需包含 reducer,如此才知道在發生某些 action 時,該怎麼做動得到目前該有的狀態(state)。所以將 reducer 引入 createStore 後,即可建立 store

const store = createStore(reducers);

store 有以下三個最主要的方法:

以計數器的例子來說:

// create a store
const store = createStore(counter);
console.log(store.getState());  // 0

// dispatch an action
store.dispatch({ type: 'INCREMENT' });
console.log(store.getState());  // 1

// subscribe a callback function
store.subscribe(() => {
  document.body.innerText = store.getState();
});

Store 篇幅比較長,會再另開一篇詳細介紹。

為什麼 React 和 Redux 這麼搭?

用這張圖就可以很容易看出來了,React 的單項資料流,不同子樹之間要交換資訊是相當麻煩的,使用 Redux 之後,元件要傳送資訊只要透過發出 action,要接收任意地方的資訊只要向 store 訂閱通知即可,元件也變得更好維護,也更有彈性。

Reference