I’m trying to build a shopping cart. Just about an hour ago I created another post with a similar problem I was running into, and that problem was solved and I was able to implement that properly.
In this shopping cart, I will display all the items in the cart on one side of the page and display the order details/pricing on the other side. Here is a visual of what I have:
As seen in the picture, with each item, I should be able to update the quantity (using the dropdown) and remove the item if necessary (the X sign on each item). My last question was regarding an issue where when I updated the dropdown (quantity) on an item, the price value of that specific item would not update. It seems that I was not properly updating the state, and I have since gotten that issue fixed.
The issue I’m running into now is that when I update the quantity on one of the items, the order summary should also update. I am using the same item (cart
) to calculate values in both.
It is important to note that I only run into this issue when I try to update the quantity of an item. When I remove an item, the order summary changes appropriately. It only doesn’t work when I try to change the quantity.
Here is the code for the component that includes the list and the order summer (titled OuterCart
):
import React, { useState } from 'react';
import CartItem from './CartItem';
import CartOrder from './CartOrder';
const OuterCart = () => {
const items = [
{
name: 'Boardwalk view',
quantity: 3,
finish: 'Non-matted',
size: '4x8',
price: 19.99,
id: 0,
},
{
name: '2 Boardwalk view',
quantity: 1,
finish: 'Matted',
size: '3x6',
price: 20.99,
id: 1,
},
... // there are more items
]
const [cart, setCart] = useState(items);
function removeItem(id) { // function run when I click the X
const newCart = cart.filter((item) => item.id !== id)
setCart(newCart);
}
function changeQuantity(event, id) { // function run when I update the dropdown on an item
let newCart = [...cart];
for (let i=0; i<cart.length; i++) {
if (cart[i].id === id) {
newCart[i] = {
...newCart[i],
quantity: parseInt(event.target.value),
}
}
}
setCart(newCart);
}
return (
<div className='px-3 text-gray-800'>
<h1 className='my-10 text-2xl font-bold'>Shopping Cart</h1>
<div className='grid grid-cols-10'>
<div className='col-span-5 flex flex-col mb-5 border-b text-gray-800'>
{cart.length === 0 ? <p>You have no items in your cart. <a href="/shop" className='text-indigo-600'>Go shopping</a> to add some!</p> : ""}
{cart.map((value, index, array) => {
return(<CartItem value={value} removeItem={removeItem} changeQuantity={changeQuantity} />)
})} // this works just fine for each item, no matter the action
</div>
<div className='col-span-1'></div>
<CartOrder cart={cart} /> // this is the order summary, only updates appropriately when I remove an item, not when I change the quantity
</div>
</div>
);
};
export default OuterCart;
If necessary, here’s the code for the Order Summary component:
import { React } from 'react';
const CartOrder = ({cart}) => {
const subtotal = cart.reduce((sum, item) => sum + item.price, 0);
const taxEstimate = parseFloat((subtotal * .06).toFixed(2));
const taxEstimateString = parseFloat(subtotal * .06).toFixed(2);
const orderTotalString = parseFloat(subtotal + taxEstimate).toFixed(2);
const orderTotal = parseFloat((subtotal + taxEstimate).toFixed(2));
return (
<div className='col-span-4 text-gray-800'>
<div className='rounded-xl bg-gray-100 px-7 py-10'>
<h1 className='text-lg font-medium mb-4'>Order summary</h1>
<div className='flex justify-between border-b py-4'>
<p className='text-gray-500 text-sm'>Subtotal</p>
<p className='font-medium text-sm'>${subtotal}</p>
</div>
<div className='flex justify-between border-b py-4'>
<p className='text-gray-500 text-sm'>Tax estimate</p>
<p className='font-medium text-sm'>${taxEstimateString}</p>
</div>
<div className='flex justify-between py-4'>
<p className='font-semibold'>Order total</p>
<p className='font-semibold'>${orderTotalString}</p>
</div>
<a href='/' className='mt-5 inline-block w-full bg-indigo-600 hover:bg-indigo-700 transition text-gray-50 text-center px-3 py-3 font-medium tracking-wide rounded-lg'>Checkout</a>
</div>
</div>
);
};
export default CartOrder;
I hate to ask two related questions in such quick succession, but I’ve been stuck on this problem for a good hour now. Any help is appreciated.