Issue
I am implementing the function of cart. But I don't know how to add up the amount of cart. Currently, the value I chose is in the form of an array in the cart, and I need to find the sum of these values. The information of the item I chose is in the state of InCart
as an array like this
{
"id": 1,
"name": "실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발",
"provider": "김영한",
"price": 88000,
"image": "https://cdn.inflearn.com/public/courses/324119/course_cover/07c45106-3cfa-4dd6-93ed-a6449591831c/%E1%84%80%E1%85%B3%E1%84%85%E1%85%AE%E1%86%B8%205%20%E1%84%87%E1%85%A9%E1%86%A8%E1%84%89%E1%85%A1%204.png",
"people" : 12400,
"free" : 4
},
I'm going to use the price in this part. I tried to make it using state total
, but I think the way to make it is wrong. How can I get the sum? I'd appreciate it if you let me know thanks!
CartAside:
import React, { useState } from 'react'
import styled from 'styled-components';
const Wrap = styled.div`
position: relative;
left: 900px;
bottom: 260px;
`
function CartAside({InCart}) {
const [total, setTotal] = useState(0)
setTotal(InCart.map((product)=>{
return total += product.price
}))
return (
<Wrap>
<div id='Price1'>
<span id='Price11'>
선택상품 금액 {total}
</span>
</div>
</Wrap>
)
}
export default CartAside;
below file is parent component
RealCart:
import CartAside from './Components/CartAside';
function RealCart({InCart}) {
return (
<div>
<Top />
<Navi />
<Cart />
<CartHeader />
{InCart.map((cart)=> {
return <CartContent key={`key-${cart.id}`} cart={cart}/>
})}
<CartAside InCart={InCart}/>
</div>
)
}
export default RealCart;
and this is top component.I upload it just in case
App.js:
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Site from './Site/Site';
import Login from './Site/Login/Login';
import SiteHomepage from './SiteHomepage/SiteHomepage';
import LecturePrecise from './LecturePrecise/LecturePrecise';
import { useSelector } from 'react-redux';
import Login1 from './SiteHomepage/Login/Login1';
import { useState } from 'react';
import RealCart from './RealCart/RealCart';
function App() {
const [Inproducts,setInproducts] = useState([])
const [InCart, setInCart] = useState([]);
// const loginButton = useSelector(state => state.loginClick.isClick);
return (
<BrowserRouter>
{/* {loginButton&&<Login1 />} */}
<Routes>
<Route path='/realCart' element={<RealCart InCart={InCart} setInCart={setInCart}/>} />
<Route path='/loginHome' element={<Site InCart={InCart} setInCart={setInCart} Inproducts={Inproducts} setInproducts={setInproducts}/>}/>
<Route path='/' element={<SiteHomepage />} />
<Route path='/lecturePrecise/:id' element={<LecturePrecise/>} />
</Routes>
</BrowserRouter>
);
}
export default App;
I made map function in the file below
Section5Bottom.jsx:
import axios from 'axios';
import React, { useEffect } from 'react';
import "../section5.css";
import Section5Card from './Section5Card';
function Section5Bottom({Inproducts, setInproducts, InCart, setInCart}) {
useEffect (()=> {
axios.get("/data/products.json").then((data)=>{
setInproducts(data.data.products);
});
},[setInproducts]);
return (
<div id='Section5Bottom'>
{
Inproducts.map((product)=>{
return <Section5Card key={`key-${product.id}`} product={product} InCart={InCart} setInCart={setInCart}/>
})
}
</div>
)
}
export default Section5Bottom;
I made the array change when I click the cart icon in this file
Section5Card.jsx:
import '../section5.css';
import {FaCartPlus} from 'react-icons/fa';
import { useDispatch } from 'react-redux';
import './card.css';
function Section5Card({product, InCart, setInCart}) {
const dispatch = useDispatch();
const handleCart = () => {
const cartItem = {
id : product.id,
image : product.image,
provider : product.provider,
price : product.price,
name : product.name
}
setInCart([...InCart, cartItem])
}
return (
<div>
<div id='CardWrap'>
<div>
<img id='Section5CardImg' src={product.image} />
</div>
<div>
<FaCartPlus size='20' style={{color:'black', position:'relative', top:'124px', left:'130px', cursor:'pointer'}} onClick={()=>{dispatch({type:"ADD"}); handleCart()}} />
</div>
<div id='CardBot'>
<div id='CardBotBPrice'>
₩{product.price}
</div>
<div id='CardBotTag'>
{product.people?
<span id='CardBotTagPeople'>
{product.people}명
</span>:
<>
<span id='CardBotTagSale'>
{product.sale}
</span>
</>}
</div>
</div>
</div>
</div>
)
}
export default Section5Card;
Solution
It's better to define another method for this using Array.prototype.reduce()
method. And since you need to update the total if your cart gets updated you need to use the useEffect
with InCart
as a dependency array.
import React, { useMemo, useState } from 'react'
import styled from 'styled-components';
const Wrap = styled.div`
position: relative;
left: 900px;
bottom: 260px;
`
function CartAside({InCart}) {
const total = useMemo(() => {
return calculateTotal(InCart);
}, [InCart])
const calculateTotal = (cartItems) => {
if(cartItems) {
return cartItems.reduce((acc, obj) => {
return acc + obj.price;
}, 0)
}else {
return 0;
}
}
return (
<Wrap>
<div id='Price1'>
<span id='Price11'>
선택상품 금액 {total}
</span>
</div>
</Wrap>
)
}
export default CartAside;
Answered By - Dulaj Ariyaratne
Answer Checked By - - Jay B. (ReactFix Admin)