I don’t have much experience in React so I want to use the quantity selected from each product and sum it up so that it can be shown in a shopping cart. I need help passing the quantities of each product to the main/root component which is App.js to make the sum to be shown on the cart possible. I prefer using functional components.
Here is my code in the two files
• App.js
import {useState} from "react"; import './App.css'; import ProductComponent from "./components/ProductComponent.jsx"; import RedmiPhoto from "./images/redmi_note_10_5G_phone.jpeg"; import HuaweiPhoto from "./images/huawei_p40_pro_phone.jpg"; import OppoPhoto from "./images/Oppo_Reno_5F.jpg"; function App() { const [productsData, setProductsData] = useState([ {name: "Oppo", cost: 13, photo: <img src={OppoPhoto} width="100px" height="100px" alt="Oppo Photo" /> }, {name: "Redmi", cost: 15, photo: <img src={RedmiPhoto} width="100px" height="100px" alt="RedMi Photo" />}, {name: "Huawei", cost: 17, photo: <img src={HuaweiPhoto} width="100px" height="100px" alt="Huawei Photo" />} ]); return ( <div className="body-section"> {productsData.map((productData, i) => <ProductComponent key={i} name={productData.name} cost={productData.cost} photo={productData.photo} />)} {/* <p><img src={iPhone} /></p> */} </div> ); } export default App;
• ProductComponent.jsx
import {useState} from "react"; const ProductComponent = ({name, cost, photo }) => { const [prodQuantity, setProdQuantity] = useState(0); const increment = () => { setProdQuantity(prodQuantity + 1); }; const decrement = () => { if(prodQuantity > 0) setProdQuantity(prodQuantity - 1); }; return( <div className="product"> <div> <div> {photo}</div> <p> {name}</p> <p> Cost: ${cost}</p> Quantity: <button onClick={decrement}>-</button> <button>{prodQuantity}</button> <button onClick={increment}>+</button> <button>Add to Cart</button> </div> </div> ); }; export default ProductComponent;
The code is available in this repository.
Picture of current app state.
Advertisement
Answer
You can pass a callback function handler from parent to child components, and then update the quantity of the product in this callback function, try this:
function App() { const [productsData, setProductsData] = useState([ {name: "Oppo", cost: 13, photo: <img src={OppoPhoto} width="100px" height="100px" alt="Oppo Photo" />, quantity: 0 }, {name: "Redmi", cost: 15, photo: <img src={RedmiPhoto} width="100px" height="100px" alt="RedMi Photo" />, quantity: 0}, {name: "Huawei", cost: 17, photo: <img src={HuaweiPhoto} width="100px" height="100px" alt="Huawei Photo" />, quantity: 0} ]); const handleProductQuantityChange = ({ name, quantity }) => { const newProductList = [...productsData] const idx = productsData.findIdx(x => x.name === name); newProductList[idx].quantity = quantity setProductsData(newProductList) } const sum = productsData.reduce((result, {cost, quantity = 0}) => { result += quantity * cost }, 0) return ( ... <div className="body-section"> <div>Total: {sum}</div> {productsData.map((productData, i) => <ProductComponent key={i} name={productData.name} cost={productData.cost} photo={productData.photo} onQuantityChange={handleProductQuantityChange} />)} {/* <p><img src={iPhone} /></p> */} </div> ) }
function ProductComponent({ name, cost, photo, onQuantityChange }) { const increment = () => { setProdQuantity(prodQuantity + 1); onQuantityChange({ name, quantity: prodQuantity + 1 }) }; const decrement = () => { if(prodQuantity > 0) { setProdQuantity(prodQuantity - 1); onQuantityChange({ name, quantity: prodQuantity - 1 }) } }; }