Please someone make me understand the underlying behavior of redux. Here is my reducer
function with one case:
case INCREASE_QTY:
return state.map((product) => {
if (product.id === action.payload.id) {
return {
...product,
data: {
...product.data,
qty: product.data.qty + action.payload.qty,
},
};
}
console.log('hello')
return product;
});
In above case, I was mistakenly returning state
instead of product
outside the if
block. This was causing unexpected behavior.
action creator:
export const increaseQty = (id, qty) => {
return {
type: INCREASE_QTY,
payload: {
id,
qty,
},
};
};
and dispatching action:
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increaseQty } from '../redux/productSlice/actions';
import { deleteFromCart } from '../redux/cartSlice/actions';
const CartCard = ({ product }) => {
const cart = useSelector((state) => state.cart);
const dispatch = useDispatch();
const deleteHandler = (id) => {
const correspondingProduct = cart.productInfo.find(
(product) => product.id === id
);
dispatch(deleteFromCart(correspondingProduct.id));
dispatch(increaseQty(correspondingProduct.id, correspondingProduct.qty));
};
return (
<div className="cartCard">
<div className="flex items-center col-span-6 space-x-6">
<img className="cartImage" src={product.data.image} alt="product" />
<div className="space-y-2">
<h4 className="cartName">{product.data.name}</h4>
<p className="cartCategory">{product.data.category}</p>
<p>
BDT <span className="cartPrice">{product.data.price}</span>
</p>
</div>
</div>
<div className="flex items-center justify-center col-span-2 mt-4 md:justify-end md:mt-0">
<button
className="removeFromCart"
onClick={() => deleteHandler(product.id)}
>
<i className="text-lg text-red-400 fa-solid fa-trash"></i>
</button>
</div>
</div>
);
};
export default CartCard;
My question is, if I have multiple products in cart and wanna delete an item, the unexpected
behavior was it was deleting all items. However I found that I was doing wrong in the reducer function. But I want to understand, if the ID
matches, hello
should not pe printed on the console. And thus the unexpected behavior would not happen. But in this case, console.log()
is being called though the if
block is executed. Why?
Thanks in advance.
Array.prototype.map()
runs for all the elements of the array. The return statement is not used to break out of the loop, as you are expecting. It is used to transform an element of an array and return a new element.
The reducer for the INCREASE_QTY
will do this:
It will run the callback for all elements of state
and transform the one where id
matches, and return rest all product
s as it is.