Reputation: 3321
Utilizing React useReducer and attempting to do state update and have react re-render as I make changes.
JSX calling the reducer:
<button onClick={() => dispatch({ type: "DECREMENT", item })} >+</button>
and the useReducer:
const reducer = (state, action) => {
const { item, type } = action;
switch (type) {
case "INCREMENT": {
const newCart = state;
const u = { ...item, quantity: item.quantity + 1 };
const index = newCart.findIndex(eachitem => item.id === eachitem.id);
newCart.splice(index, 1, u);
console.log("INCREMENT", newCart);
return newCart;
}
case "DECREMENT": {
const newCart = state;
const u = { ...item, quantity: item.quantity - 1 };
const index = newCart.findIndex(eachitem => item.id === eachitem.id);
newCart.splice(index, 1, u);
console.log("DECREMENT", newCart);
return newCart;
}
case "REMOVE": {
return state.filter(eachitem => item.id !== eachitem.id);
}
default: {
return state;
}
}
};
Full code can be found below.
Upvotes: 1
Views: 2268
Reputation: 10227
Your reducer can't detect the state change since you return the same object. The change is detected by comparing prev state value and new one, by ===
comparison or Object.is()
comparison which is basically the same thing (not sure which one, can try to find in React docs).
So instead of:
const newCart = state;
You need to do:
// shallowly copy the state so now Object.is(newState, prevState) returns false
const newCart = [...state];
...
return newCart
Upvotes: 7
Reputation: 36895
You are setting the newCart
as the state, which point to the same thing.
Either you clone the state, or return a new object instance.
switch (type) {
case "INCREMENT": {
const newCart = state;
const u = { ...item, quantity: item.quantity + 1 };
const index = newCart.findIndex(eachitem => item.id === eachitem.id);
newCart.splice(index, 1, u);
console.log("INCREMENT", newCart);
return [...newCart];
}
case "DECREMENT": {
const newCart = state;
const u = { ...item, quantity: item.quantity - 1 };
const index = newCart.findIndex(eachitem => item.id === eachitem.id);
newCart.splice(index, 1, u);
console.log("DECREMENT", newCart);
return [...newCart];
}
case "REMOVE": {
return state.filter(eachitem => item.id !== eachitem.id);
}
default: {
return state;
}
}
};
Upvotes: 2