Here are Components of REACT Cart App
import "bootstrap/dist/css/bootstrap.css";
import Cart from "./Cart";
import { CartProvider } from "./CartContext";
import "./App.css";
function App() {
return (
<CartProvider>
<Cart />
</CartProvider>
);
}
export default App;
import { createContext, useState } from "react";
import { data } from "./Data";
const CartContext = createContext();
export const CartProvider = ({ children }) => {
const [total, setTotal] = useState(0);
return (
<CartContext.Provider value={{ total, setTotal, data }}>
{children}
</CartContext.Provider>
);
};
export default CartContext;
import React from "react";
import Item from "./Item";
import { useContext } from "react";
import CartContext from "./CartContext";
function Cart() {
const { data, total } = useContext(CartContext);
return (
<div className="container">
<div className="row">
<div className="col-md-12 text-center m-3 ">
<h1>Your Cart Items</h1>
</div>
</div>
<div className="row">
<div className="col-7 text-center border border-black">
<table className="table align-middle p-2 ">
<thead>
<tr>
<th scope="col">Product</th>
<th scope="col">Price</th>
<th scope="col">Qty</th>
<th scope="col">Subtotal</th>
</tr>
</thead>
<tbody>
{data.map((product) => {
return <Item key={product.id} product={product} />;
})}
</tbody>
</table>
</div>
<div
className="col-4 ms-2 border border-black"
style={{ height: 300 }}
>
<h4 className="p-2">Total: {total}</h4>
</div>
</div>
</div>
);
}
export default Cart;
import React, { useEffect } from "react";
import { useState } from "react";
import CartContext from "./CartContext";
import { useContext } from "react";
function Item({ product }) {
const { id, img, price } = product;
const [qty, setQty] = useState(1);
const [subTotal, setSubTotal] = useState(price);
const { setTotal } = useContext(CartContext);
const handleQtyDecmnt = () => {
qty > 1 && [
setQty((qty) => qty - 1),
setSubTotal((subTotal) => subTotal - price),
];
};
const handleQtyIncremnt = () => {
[setQty((qty) => qty + 1), setSubTotal((subTotal) => subTotal + price)];
};
return (
<tr>
<td>
<img className="img-fluid" src={img} alt="" style={{ width: 100 }} />
</td>
<td>₹{price}</td>
<td>
<div className=" border border-2 rounded">
<button
onClick={handleQtyDecmnt}
type="button"
className="border-0 bg-white me-2 fs-3 "
>
-
</button>
{qty}
<button
onClick={handleQtyIncremnt}
type="button"
className="border-0 bg-white ms-2 fs-3"
>
+
</button>
</div>
</td>
<td>₹{subTotal}</td>
</tr>
);
}
export default Item;
export const data = [
{
id: 1,
img: "https://m.media-amazon.com/images/I/413OgI8KzuL._SY445_SX342_.jpg",
price: 148.0,
},
{
id: 2,
img: "https://m.media-amazon.com/images/I/41N4kMdg33L._SY445_SX342_.jpg",
price: 181.0,
},
{
id: 3,
img: "https://m.media-amazon.com/images/I/515RbDiix5L._SY342_.jpg",
price: 149.0,
},
{
id: 4,
img: "https://m.media-amazon.com/images/I/41CnSAh+qkL._SY445_SX342_.jpg",
price: 1327,
},
{
id: 5,
img: "https://m.media-amazon.com/images/I/41SzG3Zae4L._SY445_SX342_.jpg",
price: 249.0,
},
];
I would like update my cart's total amount using 'total'. When I try to use useState hook such as ,
const {total, setTotal} = useContext(CartContext)
useEffect((total)=>{total + subTotal}, [])
In that way, the total amount goes to an unpredictable way? How to update this total using the useState and useEffect hooks
You're misusing useEffect
, check the useEffect
docs to understand how and why to use it (spoiler: most of the time it's not necessary); and must call setTotal
to update the total
state.
In your case, I'm not sure when you want to trigger that update, but define a handler like the one below and call it on the event that should trigger the update (like done on onClick
on other files here):
const {setTotal} = useContext(CartContext)
const handleTotalUpdate = () => {
setTotal(previousTotal => previousTotal + subTotal)
}