[9주차/조이] 워크북 제출합니다.#91
Open
aeongiing wants to merge 5 commits into
Open
Conversation
kcleverp
reviewed
May 29, 2026
Comment on lines
+53
to
+55
| i.id === id ? { ...i, amount: i.amount - 1 } : i, | ||
| ); | ||
| return { cartItems: items, ...calcTotals(items) }; |
There was a problem hiding this comment.
Zustand 스토어 내부에서 액션이 발생할 때마다 전개 연산자를 활용해 amount와 total을 동기화 한 덕분에 외부 호출 누락으로 인한 동기화 버그는 잘 방어된 것 같습니다.
다만, 현재 구조를 보면 두 가지 아쉬운 점이 보입니다.
increase, decrease 등에서 이미 ...calcTotals로 상태를 갱신하고 있기 때문에, 하단의 calculateTotals 액션은 사실상 아무 일도 하지 않는 코드가 되어버립니다.
cartItems만 알면 언제든 유도할 수 있는 amount와 total을 스토어의 상태로 중복 저장하다 보니, 모든 액션마다 ...calcTotals(items)를 의무적으로 결합해야 하는 번거로움이 있습니다.
Zustand의 셀렉터기능을 활용해 계산 로직을 외부 커스텀 훅으로 분리하면, 중복 상태와 죽은 액션을 걷어낼 수 있습니다.
초안 코드를 첨부하겠습니다
interface CartStore {
cartItems: CartItem[];
isOpen: boolean;
increase: (id: string) => void;
decrease: (id: string) => void;
removeItem: (id: string) => void;
clearCart: () => void;
openModal: () => void;
closeModal: () => void;
}
// 스토어는 cartItems, isOpen와 액션만 관리합니다.
export const useCartStore = create<CartStore>((set) => ({
cartItems: mockCartItems,
isOpen: false,
increase: (id) =>
set((state) => ({
cartItems: state.cartItems.map((i) =>
i.id === id ? { ...i, amount: i.amount + 1 } : i
),
})),
decrease: (id) =>
set((state) => {
const item = state.cartItems.find((i) => i.id === id);
if (!item) return {};
return {
cartItems:
item.amount <= 1
? state.cartItems.filter((i) => i.id !== id)
: state.cartItems.map((i) => (i.id === id ? { ...i, amount: i.amount - 1 } : i)),
};
}),
removeItem: (id) =>
set((state) => ({
cartItems: state.cartItems.filter((i) => i.id !== id),
})),
clearCart: () => set({ cartItems: [], isOpen: false }),
openModal: () => set({ isOpen: true }),
closeModal: () => set({ isOpen: false }),
}));
// 계산용 Selector 훅 분리
export const useCartTotals = () => {
const cartItems = useCartStore((state) => state.cartItems);
const amount = cartItems.reduce((sum, item) => sum + item.amount, 0);
const total = cartItems.reduce((sum, item) => sum + Number(item.price) * item.amount, 0);
return { amount, total };
};
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
✅ 워크북 체크리스트
✅ 컨벤션 체크리스트
📌 주안점