Reputation: 1735
I have a e-commerce store when user click on add item to cart, it add to redux store.
I have a checkout page where it lists all added item, if user click on remove item, it should be removed from store. Each item in checkout page have key
as uuid.
I am using uuid to keep unique id for items when added to cart.
Suppose I have 2 items in cart , if user click delete in out item , it dispatches uuid of the item to store,
const initialState = {
items: []
};
const cart = (state = initialState, action) => {
switch (action.type) {
...
case "DELETE": {
return {
items: [
state.items.filter((item) => {
item.uuid !== action.payload;
}),
],
};
...
};
export default cart;
But after this all my cart items gets deleted and get warning in console that all items should have unique id.
Each item in state consists of below kind objects,
[{uuid: "uniqueid_1", name:'first'},{uuid: "uniqueid_2", name:'first'}]
I dispatches an remove action consists of payload as uuid (ie,"uniqueid_1")
The complete code reference below,
Action
import { v4 as uuidv4 } from "uuid";
const add = (item, quantity) => {
return {
type: "ADDTOCART",
payload: {
uuid: uuidv4(),
id: item.id,
image: item.photo,
name: item.name,
price: item.price,
quantity: quantity,
},
};
};
const remove = (item) => {
return {
type: "DELETE",
payload: item,
};
};
const removeall = () => {
return {
type: "REMOVEALL",
};
};
export default { add, remove, removeall };
REDUCER
const initialState = {
items: [],
};
const cart = (state = initialState, action) => {
switch (action.type) {
case "ADDTOCART": {
return { items: [...state.items, action.payload] };
}
case "DELETE": {
return {
items: [
state.items.filter((item) => {
item.uuid !== action.payload;
}),
],
};
}
case "REMOVEALL": {
return { items: [] };
}
default:
return state;
}
};
export default cart;
REMOVE ACTION
onClick={() => {dispatch(cartAction.remove(product.uuid));}}
Upvotes: 0
Views: 239
Reputation: 1735
I have removed curly braces from filtering and it worked
items: [
state.items.filter((item) =>
item.uuid !== action.payload;
),
],
Upvotes: 0
Reputation: 1409
Add the Spread Syntax(...) here:
items: [
...state.items.filter((item) => {
item.uuid !== action.payload;
})
],
because this:
[{uuid: "uniqueid_1", name:'first'},{uuid: "uniqueid_2", name:'first'}].filter(x=>x.uuid!=="uniqueid_1")
return an array. your items array it inside another array at the end, like this:
[[{uuid: "uniqueid_1", name:'first'}]]
And you need this:
[{uuid: "uniqueid_1", name:'first'}]
Upvotes: 1
Reputation: 1428
Your mistake could be that you now have an array too much. You can change it to:
const initialState = {
items: []
};
const cart = (state = initialState, action) => {
switch (action.type) {
...
case "DELETE": {
return {
items:
state.items.filter((item) => {
item.uuid !== action.payload.uuid;
}),
};
...
};
export default cart;
This is because state.items.filter will already return an array of objects, so you don't need to wrap it in []
Also Due to the fact that you are using the item as payload for the delete action you need to use item.uuid !== action.payload.uuid
for comparison
Upvotes: 2