code.cycling
code.cycling

Reputation: 1274

react js increment count existing object in array

I'm creating a simple Point of sale system and in my Cart reducer.

I need to check if the object is already in the Cart Array then increment the quantity. And if the Object does not exist push it into the Cart Array

The code is working as expected. But is there a better workaround ?

Cart Reducer

export const cartReducer = (state: IState, action: Actions) => {
const { uid } = action.payload

switch (action.type) {
    case 'ADD_TO_CART': {
        const cart_item = state.cart.filter(item => item.uid === uid)

        if (cart_item.length > 0) {
            return {
                ...state,
                cart: state.cart.map(item => item.uid === uid ? { ...item, quantity: item.quantity + 1 } : item)
            }
        }

        return {
            ...state,
            cart: [...state.cart, action.payload]
        }
    }
}
}

Upvotes: 1

Views: 1209

Answers (2)

Ashish
Ashish

Reputation: 4330

Instead of looping over all items twice (ones to filter and once to map) you can simply use findIndex.

The benefit of findIndex over filter: iteration will stop once the condition is fulfilled and you'll get its index, unlike filter where the loop iterates over all the elements in the array.

If your array has fewer elements, your solution is fine, but findIndex will give better performance in the case of long arrays.

switch (action.type) {
    case 'ADD_TO_CART': {
        const cartItemIndex = state.cart.findIndex(item => item.uid === uid)
        const updatedCart = [...state.cart]

        if (cartItemIndex > -1) {
            updatedCart[cartItemIndex] = { ...updatedCart[cartItemIndex], quantity: item.quantity + 1 }
        }
        else {
            updatedCart.push(action.payload)
        }

        return {
            ...state,
            cart: updatedCart
        }
    }
}

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370779

That looks mostly reasonable to me, but you could make a slight improvement by

  • declaring the new cart ahead of time instead of returning twice
  • use some instead of filter
case 'ADD_TO_CART': {
    const exists = state.cart.some(item => item.uid === uid);
    const cart = exists
        ? state.cart.map(item => item.uid === uid ? { ...item, quantity: item.quantity + 1 } : item)
        : [...state.cart, action.payload];
    return {
        ...state,
        cart
    };
}

Upvotes: 2

Related Questions