Reputation: 23
I am needing to return the total price of each product with reference to the quantity that has been added to the cart, with a single product it works fine, but when adding another product it adds the value as if it were a string and not the multiplication in total
[CartContext.js]
import React, { createContext, useState } from "react";
export const CarritoContext = createContext();
export default function CartContext({ children }) {
const [addToCarrito, setAddToCarrito] = useState([]);
const [productoRecibe] = useState({});
function addItem(item, quantity) {
const foundProdIndex = addToCarrito.findIndex(
(product) => product.item.id === item.id
);
if (foundProdIndex === -1) {
setAddToCarrito([...addToCarrito, { item, quantity }]);
} else {
const newProducts = [...addToCarrito];
newProducts[foundProdIndex].quantity += quantity;
setAddToCarrito(newProducts);
}
if (quantity === 0) {
setAddToCarrito([...addToCarrito]);
}
}
console.log(addToCarrito);
function clear() {
setAddToCarrito([]);
}
function removeItem(itemId) {
const newItems = addToCarrito.filter((item) => item.item.id !== itemId);
setAddToCarrito(newItems);
}
return (
<>
<CarritoContext.Provider
value={{
addToCarrito,
setAddToCarrito,
clear,
addItem,
removeItem,
productoRecibe,
}}
>
{children}
</CarritoContext.Provider>
</>
);
}
[Cart.js] [HERE IS THE PROBLEM IN THE H1 OF THE SECOND FOOTER]
import React, { useContext, useState } from "react";
import { Link } from "react-router-dom";
import { CarritoContext } from "../../context/CartContext";
import "./Cart.scss";
import { BsTrash } from "react-icons/bs";
const Cart = () => {
let { addToCarrito } = useContext(CarritoContext);
let { setAddToCarrito } = useContext(CarritoContext);
let { clear } = useContext(CarritoContext);
let { addItem } = useContext(CarritoContext);
let { removeItem } = useContext(CarritoContext);
console.log(addToCarrito);
return (
<>
{addToCarrito.map((producto) => {
return (
<div>
<div className="container">
<section id="cart">
<article className="product">
<header>
<img
src={producto.item.imageUrl}
alt=""
style={{
backgroundColor: "white",
width: "100%",
height: "100%",
objectFit: "contain",
}}
/>
</header>
<div className="content">
<h1>
{producto.item.name}{" "}
<BsTrash
onClick={() => removeItem(producto.item.id)}
className="basurita"
/>
</h1>
{producto.item.category} | {producto.item.brand} |{" "}
{producto.item.color}
</div>
<footer className="content">
<span className="qt">
<strong>Qty:</strong> {producto.quantity}
</span>
<h2 className="full-price">${producto.item.price}</h2>
</footer>
</article>
</section>
</div>
</div>
);
})}
<footer id="site-footer">
<div className="container clearfix">
<div className="right">
<h1 className="total">
Total: <span>${addToCarrito.map((product) => {
return product.item.price * product.quantity
})} </span>
</h1>
<Link to={'/checkout'} className="btn">Checkout</Link>
</div>
</div>
</footer>
</>
);
};
export default Cart;
Upvotes: 0
Views: 773
Reputation: 18249
The problem is that you are trying to put an array of numbers into the heading, here:
Total: <span>${addToCarrito.map((product) => {
return product.item.price * product.quantity
})} </span>
In rendering this, React will convert it to a string - and Javascript by default will stringify arrays by separating them with commas, which is why you're seeing a comma-separated string when you have more than one product.
Rendering an array directly doesn't make much sense. You say you want the total price, so you need to sum that array - which you can do with reduce
:
Total: <span>${addToCarrito.map((product) => {
return product.item.price * product.quantity
}).reduce((a, b) => a + b, 0)} </span>
Although as a stylistic point, I don't particularly like putting such a complex expression inside {...}
to render, so I'd probably define this as a constant outside the return value, so you can just render Total: <span>${totalPrice}<span>
or something like that. But I leave that decision up to you.
Upvotes: 2