Skip to content

[9주차/오스카] 워크북 제출합니다.#94

Open
OscarKang1 wants to merge 4 commits into
UMC-Inha:오스카/mainfrom
OscarKang1:오스카/9주차-제출

Hidden character warning

The head ref may contain hidden characters: "\uc624\uc2a4\uce74/9\uc8fc\ucc28-\uc81c\ucd9c"
Open

[9주차/오스카] 워크북 제출합니다.#94
OscarKang1 wants to merge 4 commits into
UMC-Inha:오스카/mainfrom
OscarKang1:오스카/9주차-제출

Conversation

@OscarKang1
Copy link
Copy Markdown

✅ 워크북 체크리스트

  • 모든 핵심 키워드 정리를 마쳤나요?
  • 핵심 키워드에 대해 완벽히 이해하셨나요?
  • 이론 학습 이후 직접 실습을 해보는 시간을 가졌나요?
  • 미션을 수행하셨나요?
  • 미션을 기록하셨나요?

✅ 컨벤션 체크리스트

  • 디렉토리 구조 컨벤션을 잘 지켰나요?
  • pr 제목을 컨벤션에 맞게 작성하였나요?
  • pr에 해당되는 이슈를 연결하였나요?(중요)
  • 적절한 라벨을 설정하였나요?
  • 파트장에게 code review를 요청하기 위해 reviewer를 등록하였나요?
  • 닉네임/main 브랜치의 최신 상태를 반영하고 있는지 확인했나요?(매우 중요!)

📌 주안점

@OscarKang1 OscarKang1 self-assigned this May 28, 2026
@OscarKang1 OscarKang1 requested a review from qkrdmsthff as a code owner May 28, 2026 08:39
@OscarKang1 OscarKang1 changed the title [오스카/9주차] 워크북 제출합니다. [9주차/오스카] 워크북 제출합니다. May 28, 2026

clearCart: () => set({ cartItems: [], amount: 0, total: 0 }),

calculateTotals: () =>
Copy link
Copy Markdown

@kcleverp kcleverp May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zustand의 사용법을 잘 알고 계시고 사용하신 것 같아 좋습니다.
하지만 기존의 calculateTotals를 외부에서 매번 수동으로 호출하게 유도하는 구조는 잠재적인 UI 동기화 버그가 있을 수 있습니다.
현재 increase, decrease, removeItem 액션들이 실행될 때, cartItems만 갱신할 뿐 amount와 total을 업데이트하지 않고 있습니다.
다른 컴포넌트에서 액션을 호출한 후 calculateTotals()를 호출해 주어야만 UI에 값이 동기화 될 것으로 보입니다.
Zustand에는 셀렉터 기능을 사용하여 상태가 변할 때 총액과 총 수량을 계산하게 하는 로직을 구축하면 다른 컴포넌트에서는 해당 훅 하나만 호출하면 스토어에 있던 구독하는 상태가 변할 때 알아서 변하는 것을 보실 수 있을 것 입니다.
초안으로 작성해본 코드를 첨부했습니다. 참고하시어 리팩토링 하면 더 좋은 코드가 될 것 같습니다

import { create } from 'zustand';
import type { CartItem } from '../types/cart';
import cartItems from '../constants/cartItems';

type CartStore = {
  cartItems: CartItem[];
  increase: (id: string) => void;
  decrease: (id: string) => void;
  removeItem: (id: string) => void;
  clearCart: () => void;
};

// 1. 스토어는 cartItems만  관리합니다.
export const useCartStore = create<CartStore>((set) => ({
  cartItems,

  increase: (id) =>
    set((state) => ({
      cartItems: state.cartItems.map((item) =>
        item.id === id ? { ...item, amount: item.amount + 1 } : item
      ),
    })),

  decrease: (id) =>
    set((state) => ({
      cartItems: state.cartItems
        .map((item) => (item.id === id ? { ...item, amount: item.amount - 1 } : item))
        .filter((item) => item.amount >= 1),
    })),

  removeItem: (id) =>
    set((state) => ({
      cartItems: state.cartItems.filter((item) => item.id !== id),
    })),

  clearCart: () => set({ cartItems: [] }),
}));

//  계산 전용 Selector 훅을 분리합니다.
export const useCartTotals = () => {
  // 스토어에서 cartItems의 변경만 구독합니다.
  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 };
};


const initialState: CartState = {
cartItems,
amount: cartItems.length,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 잘 읽었습니다! 전체적으로 구조가 촘촘히 잘 짜여 있는 좋은 코드인 것 같아요!
다음 한가지 사항만 개선되면 좋을 것 같아 리뷰 남깁니다!
현재 미션1,2,3에서 공통적으로 amount: cartItems.length로 초기화하고 있는데, amount는 아이템 개수가 아니라 각 아이템의 수량 합계여야 의미가 적합할 것 같습니다!
지금은 초기 데이터의 모든 amount가 1이라서 우연히 같은 값이 나올 수 있지만, 수량이 다른 데이터가 들어오면 틀린 값이 되어버릴 수 있어요!
다음과 같이 수정하면 좋을 것 같습니다!
amount: cartItems.reduce((sum, item) => sum + item.amount, 0),

이번 주차도 너무 수고 많으셨습니다! 기말고사 화이팅 하세용~!

Comment on lines +8 to +13
const handleConfirm = () => {
clearCart();
calculateTotals();
closeModal();
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 handleConfirm 내부를 보면 장바구니를 비운 직후 수동으로 calculateTotals()를 연속 호출되고 있습니다

스토어의 increase, decrease 같은 액션들이 일어날 때 스토어 내부에서 cartItems 변경과 동시에 합산 연산까지 한 번에 처리하도록 스토어가 리팩토링된다면 컴포넌트단에서 수동으로 calculateTotals()를 연달아 호출해 줄 필요가 사라질 것 같습니다
장바구니를 비워버리는 clearCart 액션의 경우, 스토어 내부에서 배열을 지움과 동시에 { cartItems: [], amount: 0, total: 0 } 형태로 토탈 값까지 초기화해 버리는 것이 안전합니다

스토어 리팩토링과 함께 컴포넌트단 코드를 한 줄 줄이면 깔끔하고 완성도 높은 코드가 될거같아요

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants