前一篇我們有介紹了 Redux toolkit 並且示範他是如何簡化及整併原本的專案的,那麼今天我們就陸續將其他兩項商品也搬移進現在的專案裡面吧!
在成功的移植了咖啡這項商品之後,接著我們來處理咖啡豆吧!
還記得嗎?先從 slice 開始,讓我們去對應原本的 coffeeBeanReducer 裏面的 initialState,並於目前專案下的 features/slices 內新增 coffeeBeanSlice.js 的檔案,對照之前的 reducer 並作以下的處理:
// features/slices/coffeeBeanSlice.js
const { createSlice } = require("@reduxjs/toolkit");
// only 的 coffeeBean
const initialState = {
numOfCoffeeBean: 20
}
const coffeeBeanSlice = createSlice({
name: 'coffeeBean',
initialState,
reducers: {
coffeeBeanOrdered: (state, action) => {
state.numOfCoffeeBean = state.numOfCoffeeBean - action.payload
return state;
},
coffeeBeanRestocked: (state, action) => {
state.numOfCoffeeBean = state.numOfCoffeeBean + action.payload
return state;
},
}
})
module.exports = coffeeBeanSlice.reducer;
module.exports.coffeeBeanActions = coffeeBeanSlice.actions;
因為 slice 整合了 action & reducer 的部分,所以在這裡可以很直觀地完成一條龍的作業,從原本 Reducer 檔案裡面的 initialstate 到 action 的對應,這裡可以發現 redux toolkit 幫我們把 action 作為參數帶到 reducer 裡面,這樣一來就不需要去額外定義 types 的檔案了。
和前一篇處理咖啡基本是一樣的,所以按流程我們現在必須回到 store.js 內去定義剛才新增的 slice :
// features/store.js
const configureStore = require('@reduxjs/toolkit').configureStore;
const coffeeReducer = require('./slices/coffeeSlice');
const coffeeBeanReducer = require('./slices/coffeeBeanSlice');
const store = configureStore({
reducer: {
coffee: coffeeReducer,
coffeeBean: coffeeBeanReducer,
}
})
module.exports = { store }
一樣我們於 index.js 內做以下呼叫,並測試看看:
// ./index.js
const { store } = require('./features/store');
const coffeeActions = require('./features/slices/coffeeSlice').coffeeActions;
const coffeeBeanActions = require('./features/slices/coffeeBeanSlice').coffeeBeanActions;
console.log('Initial State', store.getState());
const unsubscribe = store.subscribe(() => console.log('更新', store.getState()));
store.dispatch(coffeeActions.coffeeOrdered(1));
store.dispatch(coffeeActions.coffeeOrdered(4));
store.dispatch(coffeeActions.coffeeRestocked(10));
store.dispatch(coffeeBeanActions.coffeeBeanOrdered(2));
store.dispatch(coffeeBeanActions.coffeeBeanRestocked(5));
unsubscribe();
那麼,終端機會出現以下訊息:
Initial State { coffee: { numOfCoffee: 20 }, coffeeBean: { numOfCoffeeBean: 20 } }
更新 { coffee: { numOfCoffee: 19 }, coffeeBean: { numOfCoffeeBean: 20 } }
更新 { coffee: { numOfCoffee: 15 }, coffeeBean: { numOfCoffeeBean: 20 } }
更新 { coffee: { numOfCoffee: 25 }, coffeeBean: { numOfCoffeeBean: 20 } }
更新 { coffee: { numOfCoffee: 25 }, coffeeBean: { numOfCoffeeBean: 18 } }
更新 { coffee: { numOfCoffee: 25 }, coffeeBean: { numOfCoffeeBean: 23 } }
差不多的概念,我們還有一項蛋糕的商品,也做一樣的處理,先新增一個 cakeSlice.js,如下:
// features/slices/cakeSlice.js
const { createSlice } = require("@reduxjs/toolkit");
// 比照 only 的 cakeReducer
const initialState = {
numOfCake: 20
}
const cakeSlice = createSlice({
name: 'cake',
initialState,
reducers: {
cakeOrdered: (state, action) => {
state.numOfCake = state.numOfCake - action.payload
return state;
},
cakeRestocked: (state, action) => {
state.numOfCake = state.numOfCake + action.payload
return state;
},
}
})
module.exports = cakeSlice.reducer;
module.exports.cakeActions = cakeSlice.actions;
這裡大家就當練習熟悉一下 redux-toolkit 整合的做法,完成後,一樣回到 store.js 去做調整:
// features/store.js
const configureStore = require('@reduxjs/toolkit').configureStore;
const coffeeReducer = require('./slices/coffeeSlice');
const coffeeBeanReducer = require('./slices/coffeeBeanSlice');
const cakeReducer = require('./slices/cakeSlice');
const store = configureStore({
reducer: {
coffee: coffeeReducer,
coffeeBean: coffeeBeanReducer,
cake: cakeReducer,
}
})
module.exports = { store }
最後,於 index.js 內我們測試呼叫看看以下:
// ./index.js
const { store } = require('./features/store');
const coffeeActions = require('./features/slices/coffeeSlice').coffeeActions;
const coffeeBeanActions = require('./features/slices/coffeeBeanSlice').coffeeBeanActions;
const cakeActions = require('./features/slices/cakeSlice').cakeActions;
console.log('Initial State', store.getState());
const unsubscribe = store.subscribe(() => console.log('更新', store.getState()));
store.dispatch(coffeeActions.coffeeOrdered(1));
store.dispatch(coffeeActions.coffeeOrdered(4));
store.dispatch(coffeeActions.coffeeRestocked(10));
store.dispatch(coffeeBeanActions.coffeeBeanOrdered(2));
store.dispatch(coffeeBeanActions.coffeeBeanRestocked(5));
store.dispatch(cakeActions.cakeOrdered(3));
store.dispatch(cakeActions.cakeRestocked(6));
unsubscribe();
成功的話會如以下看到 cake 有減少和增加:
Initial State {
coffee: { numOfCoffee: 20 },
coffeeBean: { numOfCoffeeBean: 20 },
cake: { numOfCake: 20 }
}
更新 {
coffee: { numOfCoffee: 19 },
coffeeBean: { numOfCoffeeBean: 20 },
cake: { numOfCake: 20 }
}
更新 {
coffee: { numOfCoffee: 15 },
coffeeBean: { numOfCoffeeBean: 20 },
cake: { numOfCake: 20 }
}
更新 {
coffee: { numOfCoffee: 25 },
coffeeBean: { numOfCoffeeBean: 20 },
cake: { numOfCake: 20 }
}
更新 {
coffee: { numOfCoffee: 25 },
coffeeBean: { numOfCoffeeBean: 18 },
cake: { numOfCake: 20 }
}
更新 {
coffee: { numOfCoffee: 25 },
coffeeBean: { numOfCoffeeBean: 23 },
cake: { numOfCake: 20 }
}
更新 {
coffee: { numOfCoffee: 25 },
coffeeBean: { numOfCoffeeBean: 23 },
cake: { numOfCake: 17 }
}
更新 {
coffee: { numOfCoffee: 25 },
coffeeBean: { numOfCoffeeBean: 23 },
cake: { numOfCake: 23 }
}
這樣大家應該比較熟悉基本的運作了吧!
可是像 slice 這樣的做法不就沒有辦法同時作用於兩個不同的 Reducer 了嗎?
是的,這也是為什麼我們還沒處理資金的原因,下一篇我們來介紹 Redux toolkit 是如何同時影響兩個 state 的了。