iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0
自我挑戰組

30天深入淺出Redux系列 第 16

Redux 深入淺出 - [ Day 16 ] Redux Toolkit ExtraReducer 整理蛋糕

  • 分享至 

  • xImage
  •  

前篇我們整併了咖啡豆的商品,今天我們來完成最後一項蛋糕的商品,那麼相信大家也不陌生了吧!

https://ithelp.ithome.com.tw/upload/images/20220923/2012902031KezOh7F0.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({qty: 3, money: 45}));
store.dispatch(cakeActions.cakeRestocked({qty: 6, money: 30}));

unsubscribe();

這邊與前面處理咖啡、咖啡豆的情況相同,一樣是將傳入參數簡化成了 qty & money,讓原本的 pay & income 更為直覺的紀錄金額就好,剩下關於金錢的增減就交給對應的 reducer來處理,如此,這樣的處理流程要更簡單一些。

想必大家經過兩次的練習,應該知道接下來要來處理相應的 slice 檔吧!

那麼我們就回到相應的 cakeSlice 裏面做以下修正:

// 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) => {
      // 是 qty, 我加了 qty
      state.numOfCake = state.numOfCake - action.payload.qty
      return state;
    },
    cakeRestocked: (state, action) => {
      // 是 qty, 我加了 qty
      state.numOfCake = state.numOfCake + action.payload.qty
      return state;
    },
  }
})

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

調整完我們的 action function 接著我們來處理錢的問題,讓我們回到 assetsSlice 裏面,調整對應的 extraReducer,如以下:

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

const assetsSlice = createSlice({
  name: 'assets',
  initialState,
  reducers: {},
  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;
    })
    .addCase(cakeOrdered, (state, action) => {
      state.money = state.money + action.payload.money
      return state;
    })
    .addCase(cakeRestocked, (state, action) => {
      state.money = state.money - action.payload.money
      return state;
    })
  }
})

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

這裡的示範我就採我習慣的方式撰寫了,如果想要用另外一種寫法的話可以回去觀看上一篇的內容,但邏輯的部分就要靠各位自行發揮了。

完成以上修改後我們於終端機下以下指令來測試看看,assets.money 是否有因為蛋糕的增減而作相應的增減:

node index.js

如果成功應該回傳以下訊息:

Initial State {
  coffee: { numOfCoffee: 20 },
  coffeeBean: { numOfCoffeeBean: 20 },
  cake: { numOfCake: 20 },
  assets: { money: 1000 }
}
更新 {
  coffee: { numOfCoffee: 20 },
  coffeeBean: { numOfCoffeeBean: 20 },
  cake: { numOfCake: 17 },
  assets: { money: 1045 }
}
更新 {
  coffee: { numOfCoffee: 20 },
  coffeeBean: { numOfCoffeeBean: 20 },
  cake: { numOfCake: 23 },
  assets: { money: 1015 }
}

那麼至此我相信大家應該很熟悉基本的操作了,但別忘了還有非同步的部分,下一篇我們來介紹如何在 redux-toolkit 的環境下設立非同步的動作。


上一篇
Redux 深入淺出 - [ Day 15 ] Redux Toolkit ExtraReducer 整理咖啡豆
下一篇
Redux 深入淺出 - [ Day 17 ] Redux Toolkit asyncThunk 非同步範例
系列文
30天深入淺出Redux31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言