iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
自我挑戰組

30天深入淺出Redux系列 第 15

Redux 深入淺出 - [ Day 15 ] Redux Toolkit ExtraReducer 整理咖啡豆

  • 分享至 

  • xImage
  •  

前一篇我們了解了 extraReducer 的用法,並完成了咖啡商品的 slice 和 assetsSlice 裏面設定 extraReducer 綁定 coffee/coffeeOrdered 的動作,完成資金的加減。

同樣的原理,我們今天來處理另外一樣商品咖啡豆。

https://ithelp.ithome.com.tw/upload/images/20220922/201290201f2iNMjrwx.png

首先我們先回到 ./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({qty: 1, money: 10}));
// store.dispatch(coffeeActions.coffeeOrdered({qty: 4, money: 40}));
// store.dispatch(coffeeActions.coffeeRestocked({qty: 10, money: 20}));
store.dispatch(coffeeBeanActions.coffeeBeanOrdered({qty: 2, money: 10}));
store.dispatch(coffeeBeanActions.coffeeBeanRestocked({qty: 5, money: 5}));
// store.dispatch(cakeActions.cakeOrdered(3));
// store.dispatch(cakeActions.cakeRestocked(6));

unsubscribe();

格式上我們簡單改為 qty 計入數量、money 計入錢,這樣統一模組不再是以 pay & income 來處理也比較容易直觀地使用,送入之後再交由 reducers 來決定對錢與數量的增減,這裡也體現了程式設計的複用性。

接著我們回到 coffeeBeanSlice 裏面做以下修改:

// features/slices/coffeeBeanSlice.js
const { createSlice } = require("@reduxjs/toolkit");

// only 的 coffeeBean
const initialState = {
  numOfCoffeeBean: 20
}

const coffeeBeanSlice = createSlice({
  name: 'coffeeBean',
  initialState,
  reducers: {
    // 是 qty, 我加了 qty
    coffeeBeanOrdered: (state, action) => {
      state.numOfCoffeeBean = state.numOfCoffeeBean - action.payload.qty
      return state;
    },
    coffeeBeanRestocked: (state, action) => {
      // 是 qty, 我加了 qty
      state.numOfCoffeeBean = state.numOfCoffeeBean + action.payload.qty
      return state;
    },
  }
})

module.exports = coffeeBeanSlice.reducer;
module.exports.coffeeBeanActions = coffeeBeanSlice.actions;

接著我們到 assetsSlice 來修正我們的 extraReducer,新增剛剛 coffeeBeanSlice 的 actions:

// features/slices/assetsSlice.js
const { createSlice } = require("@reduxjs/toolkit");
const { coffeeOrdered, coffeeRestocked } = require('./coffeeSlice').coffeeActions;
const { coffeeBeanOrdered, coffeeBeanRestocked } = require('./coffeeBeanSlice').coffeeBeanActions;
// only assetsReducer
const initialState = {
  money: 1000,
}

const assetsSlice = createSlice({
  name: 'assets',
  initialState,
  reducers: {},
  // 這個是讓其他的slice reducer function來影響這裡的state,以下為兩種不同的寫法。
  // extraReducers: {
  //   ['coffee/coffeeOrdered']: (state, action) => {
  //     state.money = state.money + action.payload.money
  //     return state;
  //   },
  //   ['coffee/coffeeRestocked']: (state, action) => {
  //     state.money = state.money - action.payload.money
  //     return state;
  //   },
  // }
  extraReducers: (builder) => {
    builder
    .addCase(coffeeOrdered, (state, action) => {
      state.money = state.money + action.payload.money
      return state;
    })
    .addCase(coffeeRestocked, (state, action) => {
      state.money = state.money - action.payload.money
      return state;
    })
    .addCase(coffeeBeanOrdered, (state, action) => {
      state.money = state.money + action.payload.money
      return state;
    })
    .addCase(coffeeBeanRestocked, (state, action) => {
      state.money = state.money - action.payload.money
      return state;
    })
  }
})

module.exports = assetsSlice.reducer;
module.exports.cakeActions = assetsSlice.actions;

這裡我留有兩種寫法給大家做參考,這裡就看各位的喜好了,沒有對錯,如果硬要問我的話我可能會比較喜歡 builder 這種寫法,但真的是個人喜好啦!你各位可以各自選擇自己喜歡的做法就好,那第一種的話也明確地告訴你 redux-toolkit 是如何捨棄掉原先的 action type 又能同時控制其他的 initial state 的,原理上可能有所變動,但以結果上來說是一致的。

完成以上就可以來測試看看了,於終端機輸入以下指令:

node index.js

然後應該會看到以下訊息:

Initial State {
  coffee: { numOfCoffee: 20 },
  coffeeBean: { numOfCoffeeBean: 20 },
  cake: { numOfCake: 20 },
  assets: { money: 1000 }
}
更新 {
  coffee: { numOfCoffee: 20 },
  coffeeBean: { numOfCoffeeBean: 18 },
  cake: { numOfCake: 20 },
  assets: { money: 1010 }
}
更新 {
  coffee: { numOfCoffee: 20 },
  coffeeBean: { numOfCoffeeBean: 23 },
  cake: { numOfCake: 20 },
  assets: { money: 1005 }
}

那麼恭喜你又完成了一項商品,下一篇我們來完成最後一樣蛋糕的商品。


上一篇
Redux 深入淺出 - [ Day 14 ] Redux Toolkit ExtraReducer
下一篇
Redux 深入淺出 - [ Day 16 ] Redux Toolkit ExtraReducer 整理蛋糕
系列文
30天深入淺出Redux31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言