React Reducer function to return array of objects

2.1k views Asked by At

If I have an array of objects representing say a shopping cart (in React)

[ { id: 1, qty: 1 } ]

what would be a neat way of adding an item to this state ?

I would need to check if the array contains an object with that id, if it did then update it's quantity, if not then just create a new array element adding this new object.

I am getting myself in a mess trying to write this with new ES6 syntax in a functional style ... this is what I have so far ...

let initialState = []

  export default function shoppingCart(state=initialState, action) {
    switch(action.type) {
        case 'ADD_TO_CART':
            // check the array of objects and only act on the one we are interested in 
            let newQty = action.payload.qty
            console.log("state : ", state)
            for(let i = 0; i < state.length; i++) {
               if (state[i].id === action.payload.id) {
                   newQty = state[i].qty + action.payload.qty
                   console.log("QTY : " + newQty)
               }
           }
           //Obviously this will not work if the {id ...} already exists
           return [ ... state, {id:action.payload.id, qty:newQty} ] // todo: update this to contain the payload with qty included

       case 'REMOVE_FROM_CART':
           return state.filter(elem => elem.id !== action.payload.id)
       default:
           return state
   }
}
1

There are 1 answers

4
dfsq On

You can use Array.prototype.splice to replace array item with another one:

case 'ADD_TO_CART':
  const index = state.findIndex(item => item.id === action.payload.id)
  if (index > -1) {
    state.splice(index, 1, {
      id: action.payload.id,
      qty: state[index].qty + action.payload.qty
    })
    return [...state]
  }
  else {
    return [...state, {
      id: action.payload.id,
      qty: newQty
    }]
  }