Kinan Alamdar
Kinan Alamdar

Reputation: 467

How to change a value inside array of object in Redux

I have stored an array of object in Redux State and inside each object there is a key named price. Now when I increment the quantity button I need to access the object that has the key inside redux and change the price value. I was able to do that but it's not working properly the price is being changed but a new object is being added in the state of Redux you can see it in the screenshot below. hope I was able to explain the problem clearly. if not please let know so I can explain more.

enter image description here

Cart Component

increment(e, item){
  let qty = e.target.previousElementSibling.textContent;
  qty++;
  e.target.previousElementSibling.textContent = qty;
  this.props.changePrice(item);
}

<div>
  <input onClick={(e) =>this.decrement(e)} type="submit" value="-"/>
  <span>1</span>
  <input onClick={(e) => this.increment(e, item)} type="submit" value="+"/>
</div>

function mapStateToProps(state){
   return({
     itemlist: state.rootReducer
   })
 }
function mapDispatchToProps(dispatch) {
   return({
      removeItem: (item)=>{
        dispatch({type: 'removeCart', payload: item})
      },
      changePrice: (item)=>{
        dispatch({type: 'changePrice', payload: item})
      }
   })
 }
export default connect(mapStateToProps, mapDispatchToProps)(Cart);

Reducer Component

const changePrice = (itemArray, item)=>{
  let newObject = {};
  let filteredObject = itemArray.filter(reduxItem => reduxItem.id === item.id);
  let newprice = filteredObject[0].price + filteredObject[0].price;
  filteredObject[0].price = newprice;
  newObject = filteredObject;
  const something = ([...itemArray, newObject]);
  return something;
}
const reducer = (state = [], action) =>{
  switch (action.type) {
    case 'Add':
      return [...state, action.payload]
    case 'removeCart':
      const targetItemIndex = state.indexOf(action.payload);
      return state.filter((item, index) => index !== targetItemIndex)
    case 'changePrice':
         return changePrice(state, action.payload)
    default:
      return state;
  }
}
export default reducer;

Upvotes: 1

Views: 2068

Answers (2)

Hemant Parashar
Hemant Parashar

Reputation: 3774

filteredObject is an array. You override the newObject to be an array in this statement newObject = filteredObject. So the newObject is an array ( in [...itemArray, newObject] ) rather than an object. Keep things simple without unnecessary complexity.You can use Array.map. So do this instead

const changePrice = (itemArray, item) => {
  return itemArray.map(reduxItem => {
     if(reduxItem.id === item.id){
       reduxItem.price = reduxItem.price + reduxItem.price
     }

     return reduxItem
  });
};

See this for more info https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns#inserting-and-removing-items-in-arrays

Hope this helps!

Upvotes: 1

Rahul Rana
Rahul Rana

Reputation: 455

Instead of mutating the state.

// use this
const newState = Object.assign({},state);

We can create a new state and now if you do this, this works fine. This avoids mutating state.

Upvotes: 1

Related Questions