Reputation:
I try to increment a quantity property in an array of objects with React. But I can't figure out how I can reach the item to update.
What I tried:
const initialState = {
items: [{
id: 254,
quantity: 1
},
{
id: 493,
quantity: 1
}
],
};
const payload = {
id: 254
};
function updateProduct(state, action) {
return state.items.map((item, i) => {
if (item.id === action.id) {
return {
...state,
items: [
...state.items,
{
[i]: {
quantity: state.items[i].quantity + 1
}
}
]
};
}
});
}
The returned object should be:
{
items: [{
id: 254,
quantity: 2
},
{
id: 493,
quantity: 1
}
],
}
Thanks for your help !
Upvotes: 0
Views: 134
Reputation: 3
This is how I usually update items in redux store array You can do it like this:
function updateProduct(state, action) {
let updatedItems = state.items.map((item)=>{
if(item.id=== action.id){
return {...item,quantity:item.quantity+1}
}
return item
})
return {...state, items:updatedItems}
}
Upvotes: 0
Reputation: 2809
SOLUTION:
To be simple, Deep clone the object (state) and increment the specified value.
const initialState = {
items: [{
id: 254,
quantity: 1
},
{
id: 493,
quantity: 1
}
],
};
const payload = {
id: 254
};
console.log (updateProduct(initialState, payload));
function updateProduct(state, action) {
var newState = JSON.parse(JSON.stringify(state));
var isFound = false;
newState.items.forEach(item => {
for (var prop in item) {
if (prop === 'id' && item[prop] == action.id) {
item.quantity++; isFound = true; break;
}
}
if (isFound) return;
});
return newState;
}
Upvotes: 0
Reputation: 8937
You can write this as,
function updateProduct(state, action) {
return { ...state,
items: state.items.map(item => ({
...item,
quantity: action.id === item.id ? item.quantity + 1 : item.quantity
}))
}
}
Upvotes: 0
Reputation: 1013
Assuming you want
{
items: [{
id: 254,
quantity: 2
},
{
id: 493,
quantity: 2 // <<<<<<<<<<<< 2 here as well
}
],
}
and also assuming you can use the latest and greatest of ECMA Script:
const initialState = {
items: [{
id: 254,
quantity: 1
},
{
id: 493,
quantity: 1
}
],
};
const reduceIncrementQuantity = (item) => ({...item, quantity: item.quantity + 1});
const reduceIncrementQuantities = (state) => ({items: state.items.map(reduceIncrementQuantity)});
console.log(reduceIncrementQuantities(initialState));
Upvotes: 0
Reputation: 2158
first of all you have to clone/store your arr state/values in new variable
let state = [...initialState.items] // now you have all the values in state var
// and then mutate the state
let mutatedState = state.map(el => {
//modify data how you need
});
// Then assign mutatedState to initialState.items
initialState.items = mutatedState
};
Upvotes: 0
Reputation: 15688
Seems like you digged a little deep there. Based on the data you provided, isnt this as simple as:
function updateProduct(state, action) {
return state.items.map((item, i) => {
if (item.id === action.id) {
return {
...item,
quantity: item + 1
}
} else {
return item
}
});
}
Upvotes: 1
Reputation: 14375
I will suggest a few changes:
so this yields:
const reducer = (state, action) => {
const {type, payload} = action;
switch(type) {
case 'update_quantity':
const {id: itemId, quantity} = payload
return ({
...state,
items: state.items.map(item => (item.id === itemId ? {...item, quantity} : item)
default:
return state;
}
}
and then, to update:
dispatch({type: 'update_quantity', payload: {id: 'xxx', quantity: 3}});
Upvotes: 1