이 전에 수량 변경 컴포넌트인 <QuantityCounter />
에서 수량이 변경됨에 따라 product data 자체의 quantity가 변경되도록 해주었다.
그러나 장바구니 페이지를 만들면서 그렇게 하면 안된다는 것을 알았다.
<QuantityCounter />
를 product 자체의 data와 바인딩을 시키게 되면, 장바구니 페이지에서 처음 렌더링 될 때 carts(장바구니 배열)의 정보가 아닌 product의 quantity가 나타나게 된다.
따라서 Component들의 props를 다시 설정해주었다.
<App />
에 장바구니 data를 담을 배열 carts를 선언해준다.여기서 장바구니 정보 배열 carts
가 필요한 곳에 props
로 내려준다.
function App() {
const [carts, setCarts] = useState([]);
return (
<>
<Reset />
<GlobalStyle />
<BrowserRouter>
<ScrollToTop />
<Header carts={carts} />
<Routes>
<Route path='/' element={<Home />} />
<Route path='/BeautyHome' element={<BeautyHome />} />
<Route path='/SignUp' element={<SignUp />} />
<Route path='/SignIn' element={<SignIn />} />
<Route path='/Cart' element={<Cart carts={carts} setCarts={setCarts} />} />
<Route path='/Product/:id' element={<Product carts={carts} setCarts={setCarts}/>} />
</Routes>
<Footer />
</BrowserRouter>
</>
);
}
<Product />
에서는 count
변수를 통해 <QuantityCounter />
를 제어한다.count
는 carts
에 들어갈 cartItem
에 이용된다. → cart.count 만큼 carts
에 들어감.
function Product({ carts, setCarts }) {
const {id} = useParams();
const[products, setProducts] = useState([]);
useEffect( () => {
fetch('http://localhost:3000/data/product.json',{
method: 'GET'})
.then(res => res.json())
.then(data => {
setProducts(data);
});
},[])
let product = [];
for(let i=0; i<products.length; i++){
if(products[i].id === Number(id)){
product = products[i];
break;
}
}
const[count, setCount] = useState(1);
const getCount = (count) => {
setCount(count);
}
const setQuantity = (id, quantity) => {
const found = carts.filter((el) => el.id === id)[0];
const idx = carts.indexOf(found);
const cartItem = {
id: product.id,
name: product.name,
description: product.description,
img: product.img,
price: product.price,
quantity: quantity,
delivery: product.delivery,
keep: product.keep,
checked: true
};
setCarts([ ...carts.slice(0, idx), cartItem, ...carts.slice(idx+1) ]);
Swal.fire({
text: '장바구니에 추가되었습니다.',
confirmButtonText: '확인',
confirmButtonColor: 'rgb(95, 0, 128)'
});
}
const addToCart = () => {
const cartItem = {
id: product.id,
name: product.name,
description: product.description,
img: product.img,
price: product.price,
quantity: count,
delivery: product.delivery,
keep: product.keep,
checked: true
};
const found = carts.find((el) => el.id === cartItem.id);
if(found) {
setQuantity( cartItem.id, found.quantity + count );
} else {
setCarts([...carts, cartItem]);
Swal.fire({
text: '장바구니에 추가되었습니다.',
confirmButtonText: '확인',
confirmButtonColor: 'rgb(95, 0, 128)'
});
}
}
const PlusQuantity = () => {
getCount(count => count + 1);
}
const MinusQuantity = () => {
if (count>=2) {
getCount(count => count - 1);
}
else return;
}
return (
blah~
<div className={styles.QuantityCounter}>
<button class={styles.minusButton} onClick={MinusQuantity}>-</button>
<button class={styles.quantityButton}>{count}</button>
<button class={styles.plusButton} onClick={PlusQuantity}>+</button>
</div>
blah~
);
}
<CartProudct />
에선 carts
배열에 들어있는 cartItem
만큼의 quantity를 렌더링 해야하기 때문에 carts.map
으로 가져온 cart
의 quantity를 이용한다.function CartProduct({ carts, cart, setCarts, getNowQuantity }) {
const[ counterQuantity, setCounterQuantity ] = useState(1);
const PlusQuantity = () => {
setCounterQuantity(counterQuantity => counterQuantity + 1);
cart.quantity += 1;
getNowQuantity(cart.quantity);
}
const MinusQuantity = () => {
if (cart.quantity>=2) {
setCounterQuantity(counterQuantity => counterQuantity - 1);
cart.quantity -= 1;
getNowQuantity(cart.quantity);
}
else return;
}
const removeFromCart = (id) => {
setCarts(carts.filter( (el) => el.id !== cart.id ));
}
return (
blah~
<div className={styles.QuantityCounter}>
<button class={styles.minusButton} onClick={MinusQuantity}>-</button>
<button class={styles.quantityButton}>{cart.quantity}</button>
<button class={styles.plusButton} onClick={PlusQuantity}>+</button>
</div>
blha~
);
}