Hi i am pretty new to React.
Here is my code:
const cartCtx=useContext(CartContext);
const cartItems = (
<ul className={classes['cart-items']}>
{cartCtx.items.map((item) => (
<CartItem
key={item.id}
name={item.name}
amount={item.amount}
price={item.price}
onAdd={cartCtx.addItem(item)}
....
I am trying to add item by calling onAdd function which existed in my ReactContext.
However, I get this error when running:
Warning: Cannot update a component (CartProvider
) while rendering a different component (Cart
). To locate the bad setState() call inside Cart
.
After I change onAdd function call to an arrow function:
const cartItems = (
<ul className={classes['cart-items']}>
{cartCtx.items.map((item) => (
<CartItem
key={item.id}
name={item.name}
amount={item.amount}
price={item.price}
onAdd={()=>cartCtx.addItem(item)}
....
The problem gets resolved.
Here is my onAdd function inside ReactContext:
const defaultCartState = {
items: [],
totalAmount: 0
};
const cartReducer = (state, action) => {
if (action.type === 'ADD') {
const updatedTotalAmount = state.totalAmount + action.item.price * action.item.amount;
const existingCartItemIndex=state.items.findIndex((item)=>item.id===action.item.id);
const existingCartItem=state.items[existingCartItemIndex]
let updatedItems;
let updateItem;
if (existingCartItem){
updateItem={...existingCartItem,
amount:action.item.amount+existingCartItem.amount
}
updatedItems=[...state.items]
updatedItems[existingCartItemIndex]=updateItem;
}
else{
updatedItems = state.items.concat(action.item);}
return {
items: updatedItems,
totalAmount: updatedTotalAmount
};
}
return defaultCartState;
};
const CartProvider = (props) => {
const [cartState, dispatchCartAction] = useReducer(cartReducer, defaultCartState);
const addItemToCartHandler = (item) => {
dispatchCartAction({type: 'ADD', item: item});
};
const cartContext = {
items: cartState.items,
totalAmount: cartState.totalAmount,
addItem: addItemToCartHandler
};
return (
<CartContext.Provider value={cartContext}>
{props.children}
</CartContext.Provider>
);
};
export default CartProvider;
Does anyone know why this happens and what is the logic behind the scene?