Skip to content

Commit 75780ec

Browse files
committed
refactor: useCart 함수 다일책임원칙 리팩토링
1 parent 95c9395 commit 75780ec

File tree

3 files changed

+42
-52
lines changed

3 files changed

+42
-52
lines changed

src/basic/App.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,7 @@ const App = () => {
9494
removeFromCart,
9595
clearCart,
9696
getProductRemainingStock,
97-
isInCart,
98-
getCartItem,
99-
} = useCart(addNotification);
97+
} = useCart();
10098

10199
const totalItemCount = getCartItemCount(cart);
102100

src/basic/components/MainPage.tsx

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useCallback } from "react";
22
import { CartItem, Coupon, Product } from "../../types";
33
import { displayPrice } from "../utils/formatters";
44
import { getRefinedProduct } from "../utils/productUtils";
5+
import { getRemainingStock } from "../utils/cartUtils";
56

67
interface MainPageProps {
78
products: Product[];
@@ -42,23 +43,43 @@ export function MainPage({
4243
calculateCartTotal,
4344
calculateItemTotal,
4445
coupons,
45-
getProductRemainingStock,
4646
}: MainPageProps) {
4747
// 장바구니에 상품 추가 (props로 받은 함수 사용)
4848
const handleAddToCart = useCallback(
4949
(product: Product) => {
50+
if (!getRemainingStock(product, cart)) {
51+
addNotification("재고가 부족합니다", "error");
52+
return;
53+
}
54+
5055
addToCart(product, 1);
56+
5157
addNotification("장바구니에 담았습니다", "success");
5258
},
53-
[addToCart, addNotification]
59+
[cart, addToCart, addNotification]
5460
);
5561

5662
// 장바구니 상품 수량 변경 (props로 받은 함수 사용)
5763
const handleUpdateQuantity = useCallback(
58-
(productId: string, newQuantity: number) => {
59-
updateCartItemQuantity(productId, newQuantity);
64+
(product: Product, newQuantity: number) => {
65+
if (newQuantity <= 0) {
66+
removeFromCart(product.id);
67+
return;
68+
}
69+
70+
if (newQuantity > product.stock) {
71+
addNotification?.(`재고는 ${product.stock}개까지만 있습니다.`, "error");
72+
return;
73+
}
74+
75+
if (!getRemainingStock(product, cart)) {
76+
addNotification("재고가 부족합니다", "error");
77+
return;
78+
}
79+
80+
updateCartItemQuantity(product.id, newQuantity);
6081
},
61-
[updateCartItemQuantity]
82+
[addNotification, cart, removeFromCart, updateCartItemQuantity]
6283
);
6384

6485
// 쿠폰 적용
@@ -294,7 +315,7 @@ export function MainPage({
294315
<button
295316
onClick={() =>
296317
handleUpdateQuantity(
297-
item.product.id,
318+
item.product,
298319
item.quantity - 1
299320
)
300321
}
@@ -308,7 +329,7 @@ export function MainPage({
308329
<button
309330
onClick={() =>
310331
handleUpdateQuantity(
311-
item.product.id,
332+
item.product,
312333
item.quantity + 1
313334
)
314335
}

src/basic/hooks/useCart.ts

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
import { useCallback, useState, useEffect } from "react";
1+
import { useCallback, useState } from "react";
22
import { CartItem, Product } from "../../types";
33
import { getRemainingStock } from "../utils/cartUtils";
44

5-
export const useCart = (
6-
addNotification?: (
7-
message: string,
8-
type: "error" | "success" | "warning"
9-
) => void
10-
) => {
5+
export const useCart = () => {
116
const [cart, _setCart] = useState<CartItem[]>(() => {
127
const saved = localStorage.getItem("cart");
138
if (saved) {
@@ -38,16 +33,6 @@ export const useCart = (
3833
// 장바구니에 상품 추가
3934
const addToCart = useCallback(
4035
(product: Product, quantity: number = 1) => {
41-
const remainingStock = getRemainingStock(product, cart);
42-
43-
if (quantity > remainingStock) {
44-
addNotification?.(
45-
`재고는 ${remainingStock}개까지만 있습니다.`,
46-
"error"
47-
);
48-
return;
49-
}
50-
5136
setCart((prev) => {
5237
const existingItem = prev.find(
5338
(item) => item.product.id === product.id
@@ -59,52 +44,38 @@ export const useCart = (
5944
? { ...item, quantity: item.quantity + quantity }
6045
: item
6146
);
62-
} else {
63-
return [...prev, { product, quantity }];
6447
}
48+
49+
return [...prev, { product, quantity }];
6550
});
6651
},
67-
[cart, addNotification]
52+
[setCart]
6853
);
6954

7055
// 장바구니에서 상품 수량 변경
7156
const updateCartItemQuantity = useCallback(
7257
(productId: string, quantity: number) => {
73-
if (quantity <= 0) {
74-
removeFromCart(productId);
75-
return;
76-
}
77-
7858
setCart((prev) => {
79-
const item = prev.find((item) => item.product.id === productId);
80-
if (!item) return prev;
81-
82-
// 상품의 총 재고만큼만 허용
83-
if (quantity > item.product.stock) {
84-
addNotification?.(
85-
`재고는 ${item.product.stock}개까지만 있습니다.`,
86-
"error"
87-
);
88-
return prev;
89-
}
90-
9159
return prev.map((item) =>
9260
item.product.id === productId ? { ...item, quantity } : item
9361
);
9462
});
9563
},
96-
[addNotification]
64+
[setCart]
9765
);
9866

9967
// 장바구니에서 상품 제거
100-
const removeFromCart = useCallback((productId: string) => {
101-
setCart((prev) => prev.filter((item) => item.product.id !== productId));
102-
}, []);
68+
const removeFromCart = useCallback(
69+
(productId: string) => {
70+
setCart((prev) => prev.filter((item) => item.product.id !== productId));
71+
},
72+
[setCart]
73+
);
10374

10475
// 장바구니 비우기
10576
const clearCart = useCallback(() => {
10677
setCart([]);
107-
}, []);
78+
}, [setCart]);
10879

10980
// 상품의 재고 확인
11081
const getProductRemainingStock = useCallback(

0 commit comments

Comments
 (0)