Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reactjs context reducer increment data

How to increment the array value inside the object.

I tried the code below but It's removing the garments array and replacing it with shirts: Nan value

export const initialState = {
    booking: {
       expPrice: 0,
       garments: [
        {
            shirts: 0
        },
        {
            pants: 0
        },
        {
            etc: 0
        }
    ]
},
bookings: []
};

export const bookingsReducer = (state, action) => {
   switch (action.type) {
    case 'INCREMENT_SHIRT': {
        return {
            ...state,
            booking: {
                ...state.garments,
                shirts: state.shirts + 1 // how to increment 
            }
        };
    }
    default:
        return state
   }
}
like image 799
Code.Freeze Avatar asked Mar 16 '26 21:03

Code.Freeze


2 Answers

You're trying to spread the properties of your garments array into your new booking object, however, as state doesn't have a garments property you'll be spreading undefined (which is a no-op). Moreover, if it did hold your array, you would be spreading the indexes of your array as keys to your new object. You're also adding a shirt property to your booking object, which you don't want to do as you want to keep this property inside the objects of your garments array.

Instead, spread the state.booking properties into your booking object, and then overwrite the garments property with a new array to be the mapped version of your current garments array. When you're mapping, if you find an object with a shirts property, you can increment its value by adding one to the current value, otherwise, you can return the current object:

return {
  ...state,
  booking: {
    ...state.booking,
    garments: state.booking.garments.map(
      obj => obj.hasOwnProperty('shirts') ? {shirts: obj.shirts+1} : obj
    ) 
  }
};
like image 83
Nick Parsons Avatar answered Mar 18 '26 11:03

Nick Parsons


Issue

You are spreading an undefined value state.garments that should actually be state.bookings.garments, so garments array isn't copied to the new state. Similarly, state.shirts is undefined and any mathematical operation with it results in a NaN value.

Solution

You should shallow copy all nested state object properties.

For the given state:

{
  booking: {
    expPrice: 0,
    garments: [
      { shirts: 0 },
      { pants: 0 },
      { etc: 0 }
    ]
  },
  bookings: []
}

Reducer logic

case 'INCREMENT_SHIRT': {
  return {
    ...state,
    booking: {
      ...state.booking,
      garments: state.booking.garments.map((cat, i) => i === 0 ? {
        ...cat,
        shirts: cat.shirts + 1,
      } : cat),
    }
  };
}
like image 24
Drew Reese Avatar answered Mar 18 '26 09:03

Drew Reese



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!