bier hier
bier hier

Reputation: 22550

How to calculate the total price of all items in reducer?

I am trying to build a shoppingcart app in reactjs/redux and this is 1 of my reducers:

const initialState = {
    items: [],
    cartOpen:true
}

    const Cart = (state = initialState, action) => {
        switch (action.type) {
            case 'ADD_TO_CART':
                return [...state, action.payload]
            default:
                return state
        }
    }

    export default Cart;

The other reducer contains the data ie items for the app:

const Data = (state = initialState, action) => {
    switch (action.type) {
        case 'GET_DATA_SUCCESS':
            return Object.assign({}, state, { datas: action.data });
        case 'GET_DATA_FAIL':
            return Object.assign({}, state, { datas: action.data });

        default:
            return state
    }
}

When the ADD_TO_CART action is dispatched I want to calculate the new total for the cart. I am looking for a way to calculate the total price of al the items in the cart when the cart is updated.

Upvotes: 1

Views: 2969

Answers (2)

Mark Williams
Mark Williams

Reputation: 2308

If the action that causes the items to change is GET_DATA_SUCCESS then you could calculate the total price in the same reducer and set a new state property accordingly, so something like:

case 'GET_DATA_SUCCESS':
  let totalPrice = getTotalPrice(action.data);
  return Object.assign({}, state, { datas: action.data, cartTotal: totalPrice });

(If the price can change for a retrieval failure you'd need to recalculate the price and set it in both case clauses.)

If you don't want to set two parts of the state in this clause you could break it up into two reducers, both acting on (say) GET_DATA_SUCCESS but setting the separate parts of the state (one for datas, one for cartTotal).

As a complete alternative, and bearing in mind the preference to keep state normalized; you could just leave the items in the state and use a helper function elsewhere to calculate total price on rendering. If the number of items is relatively small and the calculation is simple then this may well be worth considering. This is well worth reading:

http://redux.js.org/docs/recipes/ComputingDerivedData.html

Upvotes: 1

abhirathore2006
abhirathore2006

Reputation: 3745

you can do something like this.

const initialState = {
    items: [],
    cartOpen:true,
    total:0,
}

const Cart = (state = initialState, action) => {
    switch (action.type) {
        case 'ADD_TO_CART':
            let newstate =  [...state, action.payload];
            let newTotal = 0;
            newstate.items.forEach(item=>{
               newTotal+=item.price;
            });
            newstate.total =newTotal;
            return newstate ; 
        default:
            return state
    }
}

export default Cart;

Upvotes: 1

Related Questions