本文目標:希望通過買水果的例子,和大家探討下
redux
的基礎用法,能快速入門redux
。
例子:買水果
一天,程式設計師阿大(化名)想要去買水果吃,發現小區周圍居然沒有水果店,於是就打算自己開一個水果店賺點小錢。
阿大分析了一下水果店的營業模式。其實就是處理每一位顧客的需求,然後記賬看看每天的盈虧。那麼抽象成程式就是監聽顧客的行為,並把每個行為的結果都記在賬上,這正好是 redux
所擅長的。阿大胸有成竹,說著就開始寫了起來:
首先模擬顧客的購買行為:
const action = {
type: 'BUY_APPLE', // 買蘋果
payload: {
count: 2 // 買 2 斤
}
}
複製程式碼
那不同的顧客要的斤數可能不同,於是他寫了下面這個方法:
/**
* 只要知道斤數就可以快速生成顧客的各種需求
* @param {number} num 顧客要買的斤數
*/
function buyApple(num) {
return {
type: 'BUY_APPLE',
payload: {
count: num
}
}
}
複製程式碼
然後是賬本的結構,記錄每天賣了多少斤:
// 被託管的資料 state
// 賬本,今天已賣的蘋果:0 斤;為了簡便,就只舉一個例子,事實上還有很多其他水果,大家自行腦補
const state = { apple: 0 };
複製程式碼
好了,現在顧客需求,賬本都有了,那誰來記賬呢?所以阿大請了一個收銀員負責記賬,並告訴他這麼記賬:
/**
* 監聽函式 listener
* 收銀員只要知道顧客的需求就能正確的操作賬本
* @param {object} state 賬本
* @param {object} action 顧客的需求
*/
function reducer(state, action) {
// 註冊 ‘買蘋果’ 事件
// 如果有人買了蘋果,加上顧客買的斤數,更新賬本
if (action.type === 'BUY_APPLE') {
return Object.assign({}, state, {
apple: state.apple + action.payload.count
});
}
// 沒註冊的事件不作處理
// 買我們們店裡沒有的東西,不更新賬本,原樣返回
return state;
}
複製程式碼
好,萬事俱備,可以正式的監聽顧客的購買需求並更新賬本了:
const { createStore } = require('redux');
// 建立水果店需要收銀員(監聽函式 listener)和賬本(被託管的資料)
const store = createStore(reducer, state);
複製程式碼
不僅如此,redux
還提供了一個功能,每服務一個顧客,都可以額外做一些事情,於是阿大就想看看每筆交易之後的賬本:
// store.getState() 可以獲取最新的 state
store.subscribe(() => console.log(JSON.stringify(store.getState())));
複製程式碼
好了,顧客開始來買水果了:
// 觸發使用者購買水果的事件
// 銷售員開始銷售
store.dispatch(buyApple(3)); // {"apple":3}
store.dispatch(buyApple(4)); // {"apple":7}
複製程式碼
店鋪穩定的運營了下去,阿大心裡美滋滋~
講解
上面的例子涉及到了 redux 的幾個概念:action,action creator,state,store。
不過在此之前要先說 redux 特別講究也是特別重要的 3 點:
- 只能有唯一的 store 物件儲存整個應用的 state
- state 是隻讀的,只能通過 dispatch(action) 的方式來改變 state
- reducer 必須是純函式
action
action
是行為資訊的抽象,物件型別,它描述發生了什麼。這個物件必須有一個 type
屬性,對於物件裡面的其他內容,redux 不做限制。但是推薦符合 Flux Standard Action 規範:
{
type: 'ACTION_TYPE',
payload, // action 攜帶的資料
}
複製程式碼
action creator
action creator
顧名思義就是用來建立 action 的,action creator 只簡單的返回 action。
function createAction(num) {
return {
type: 'ACTION_TYPE',
payload,
}
}
複製程式碼
state
state
是被託管的資料,也就是每次觸發監聽事件,我們要操作的資料。
reducer
reducer 是用來控制 state 改變的函式。action 描述了發生了什麼,但是並不會知道相應的 state 該怎麼改變。對於不同的 action,相應的 state 變化是用 reducer 來描述的。
reducer 接受兩個函式,第一個是 state
,第二個是 action
,並返回計算之後新的 state。reducer 必須是一個純函式,對於相同的輸入 state 和 action,一定會返回相同的新的 state。
nextState = reducer(prevState, action);
複製程式碼
因為 reducer 是純函式,所以原來的 prevState
並不會改變,新的 nextState
是一個最新的快照。
store
store
是把上面三個元素合起來的一個大物件:
{
createStore,
combineReducers,
bindActionCreators,
applyMiddleware,
compose,
__DO_NOT_USE__ActionTypes
}
複製程式碼
它負責:
- 託管應用的 state
- 允許通過
store.getState()
方法訪問到託管的 state - 允許通過
store.dispatch()
方法來觸發 action 更新 state - 允許通過
store.subscribe()
註冊監聽函式監聽每一次的 action 觸發 - 允許登出通過
store.subscribe()
方法註冊的監聽函式
// 註冊
const unsubscribe = store.subscribe(() => { /** do something */});
// 登出
unsubscribe();
複製程式碼
圖解
程式碼地址:Redux 入門 -- 基礎用法,直接控制檯執行
node ./demo1/index.js
檢視效果
上一篇:Redux 是什麼