Reputation: 396
I am new to React Hooks and I'm trying to update the quantity in a shopping cart using the following code;
import React, { useState, useEffect } from "react";
import cookie from "react-cookies";
import CheckoutItems from "./CheckoutItems";
import restHelper from "../../shared/RestHelper";
const Checkout = () => {
const [cart, setCart] = useState(null);
useEffect(() => {
const cartId = cookie.load("RbCartId");
if (cartId){
(async () => {
const cart = await restHelper.getUserCart(cartId);
setCart(cart);
})();
}
}, []);
const handleQtyUpdate = (evt, id) => {
let _cart = cart;
let items = _cart.cartItems.filter(x => x.id === id);
let cartItem = { ...items[0] };
cartItem.quantity = Number(evt.target.value);
const index = _cart.cartItems.findIndex(x => x.id === cartItem.id);
_cart.cartItems[index] = cartItem;
setCart(_cart);
};
return (
<section>
<div className="container" style={{ marginTop: "80px" }}>
<h3 className="rb-highlight">Shopping Cart</h3>
<table className="table" style={{marginTop: "20px"}}>
<thead>
<tr>
<th>Items</th>
<th style={{ textAlign: "right" }}>Price</th>
<th style={{ textAlign: "right" }}>Quantity</th>
<th style={{ textAlign: "right" }}>Total</th>
</tr>
</thead>
<tbody>
<CheckoutItems cart={cart} onQtyUpdate={handleQtyUpdate} />
</tbody>
</table>
</div>
</section>
);
}
export default Checkout;
The CheckoutItems component is
import React from "react";
function CheckoutItems({cart, onQtyUpdate}){
if (!cart || cart.cartItems === 0){
return <tr><td colSpan="4"><span className="rb-highlight">There are no items in your cart</span></td></tr>;
}
else{
const cartItems = cart.cartItems.map((item, index) => {
return <tr key={index}>
<td>{item.description}</td>
<td style={{textAlign: "right"}}>€{item.cost}</td>
<td style={{textAlign: "right"}}><input type="text" id={item.id} name="quantity" value={item.quantity} onChange={(evt) => onQtyUpdate(evt, item.id)} /></td>
<td style={{textAlign: "right"}}>€{item.cost * item.quantity}</td>
</tr>
})
return cartItems;
}
}
export default CheckoutItems;
The cart items are successfully updated in handleQtyUpdate
however the value isn't updated in the UI. From what I have read I should be using useEffect
to update the cart but I'm not sure how to go about using it from handleQtyUpdate
.
Upvotes: 6
Views: 7687
Reputation: 1220
You should have a copy of the object using spread operator
setCart({..._cart})
Upvotes: 0
Reputation: 82096
The issue is state comparisons are shallow, meaning, in the case of an object only the reference will be compared.
In your example, you update the cartItems
property but not the object instance, so as far as React is concerned the state hasn't changed because it won't check individual properties.
Try creating a completely new cart each time and you should see the UI update e.g.
setCart({ ..._cart })
Upvotes: 23