when checking it in console the result is fine, but if replace that array in setCart its not happening , RecoilJS
const cartState=[
{ id:1, productName:'Apple',price:100,quantity:1}
{ id:2, productName:'Cherry',price:70,quantity:1}
{ id:3, productName:'Orange',price:60,quantity:1}
{ id:4, productName:'Grapes',price:69,quantity:1}
]
const [cart, setCart] = useRecoilState(cartState)
object is { id:4, productName:'Grapes',price:69,quantity:1}
const addToCart =(object) => {
if(!cart.includes(object))
{
setCart([...cart, object])
}else
{
let f= cart.map(items=>
{
if(items.id==object.id)
{
return {...items, quantity:items.quantity+ 1}
}
return items
})
setCart(f)
}
}
Array.prototype.includes
basically uses shallow reference equality. Primitives and String types are always equal to themselves by value, but objects must refer to the exact same reference in memory in order for .includes
to work for them. This is hardly ever the case in React though when the new item being added to the cart is typically going to be a new object as well.
It is always safer to match objects by specific properties.
Search and match by the cart item ids. If some item in the cart has a matching id
property, then update the cart, otherwise add the new item to the cart array.
I suggest to also use functional state updates to correctly update from the previous state, not any cart state closed over in any scopes. These can sometimes be stale references, especially if addToCart
is called in any loops to add multiple items.
const addToCart = (newItem) => {
if (cart.some(item => item.id === newItem.id)) {
setCart(cart => cart.map(item => item.id === newItem.id
? { ...item, quantity: item.quantity + 1 }
: item,
));
} else {
setCart(cart => [...cart, newItem]);
}
}