[Redux] Redex 核心概念筆記
Flux 為 Facebook 提出的一個架構,用以方便管理 React 錯綜複雜的 state 及 action 關係。而 Redux 大幅簡化了 Flux 的概念。
要學習 Redux 強烈建議透過原作者的影片:https://egghead.io/lessons/javascript-redux-the-single-immutable-state-tree
Redux 三大元件和三大原則:
三大元件:
- action: 描述發生的事件類別(type),以及所承載的資訊(payload)。
- reducer: 一個函式,負責將給定的 state 根據給定的 action 做變化而得到新的 state。
- store: 整個 Redux 運作的核心,負責儲存整個 state tree,每個專案只會有一個 store。
三大原則:
- 唯一資訊來源:整個專案的 state,被儲存在一個樹狀物件放在唯一的 store 裡面。
- State 是唯讀的:改變 state 的唯一的方式是發出一個 action,也就是一個描述發生什麼事的物件。
- 變更被寫成 pure function:要指定 state tree 如何藉由 action 來轉變,你必須撰寫 pure reducer。
Redux 運作流程
(圖片來源)
以上的圖片就是一個簡單的流程:
- 事件發生: 例如使用者點擊某元件
onclick
- 發送 action: Action Creator 向 Store 發送 action
- 更改 state: Store 調用 Reducer ,給予 state 和 action 而得到新的 state。
- 發佈通知: 需要用到 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
只會且只能有一個,而且所有東西都會被包在裡面(reducer
和middleware
等等)
store
需包含 reducer
,如此才知道在發生某些 action
時,該怎麼做動得到目前該有的狀態(state)。所以將 reducer
引入 createStore
後,即可建立 store
:
const store = createStore(reducers);
store 有以下三個最主要的方法:
store.getState()
: 顧名思義就是可以得到目前的狀態state
store.dispatch(action);
:發送一個動作給 store,store 會找到reducer
執行後,得到新的state
store.subscribe(render);
:向store
訂閱dispatch
事件,當dispatch
發生時會執行訂閱的 callback (render
)
以計數器的例子來說:
// 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
-
https://chentsulin.github.io/redux/docs/introduction/ThreePrinciples.html
-
http://huli.logdown.com/posts/294037-javascript-redux-basic-tutorial