1

I use redux - toolkit in my app with createAsyncThunk. I have some "cart" reducer and inside it I have "CART_CLEARED" action. "CART_CLEARED" is being called when user press on "Clear Cart" button.

But now, I also have to clear cart when user made order. So, when user made order, I dispatch "createOrder" thunk (created with createAsyncThunk) and then, in same "cart" reducer, listen for "createOrder.fulfilled" action and I have to do the same thing - clear my cart products.

const initialState = {
  products: {};
}

export const cartSlice = createSlice({
  name: "cart",
  initialState,
  reducers: {
    ...some reducers,
    
    CART_CLEARED: (state) => {
      state.products = initialState.products
    },
  },
  extraReducers: (builder) => {
    builder.addCase(createOrder.fulfilled, (state) => {
      state.products = initialState.products
    });
  },
});

Is it normal practice to move this handler into a separate function? or is there some other solution possible within redux?

const initialState = {
  products: {};
}

const CART_CLEARED_HANDLER = (state) => {
  state.products = initialState.products
}

export const cartSlice = createSlice({
  name: "cart",
  initialState,
  reducers: {
    ...some reducers,

    CART_CLEARED: (state) => CART_CLEARED_HANDLER(state)
  },
  extraReducers: (builder) => {
    builder.addCase(createOrder.fulfilled, (state) => CART_CLEARED_HANDLER(state));
  },
});
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
eugenedrvnk
  • 408
  • 1
  • 5
  • 10
  • IMO, if you're going to change more than one state variable (in CART_CLEARED handler), reusing a separate function makes better sense (reduces maintenance cost, causes less bug, etc), if it will stay as simple as in your example, then it's ok to use it like this. – sardok Jul 21 '21 at 09:25
  • I think `createOrder` action belongs to `orders` slice. In my opinion, clearing cart in `createOrder` thunk is not a good approach. Instead, you need to dispatch `CART_CLEARED` action after order is created in your component. – glinda93 Jul 21 '21 at 09:28

1 Answers1

1

I don't why you wouldn't want to make your code more DRY (Don't Repeat Yourself).

I'd reduce this a bit more by removing the anonymous function too, just assign the reducer function to the case.

const initialState = {
  products: {};
}

const clearCartHandler = (state) => {
  state = initialState;
}

export const cartSlice = createSlice({
  name: "cart",
  initialState,
  reducers: {
    ...some reducers,
    CART_CLEARED: clearCartHandler
  },
  extraReducers: (builder) => {
    builder.addCase(createOrder.fulfilled, clearCartHandler);
  },
});
Drew Reese
  • 165,259
  • 14
  • 153
  • 181