Skip to content

Conversation

@Toeam
Copy link

@Toeam Toeam commented Dec 2, 2025

basic배포 : https://toeam.github.io/front_7th_chapter3-2/index.basic.html

과제의 핵심취지

  • React의 hook 이해하기
  • 함수형 프로그래밍에 대한 이해
  • 액션과 순수함수의 분리

과제에서 꼭 알아가길 바라는 점

  • 엔티티를 다루는 상태와 그렇지 않은 상태 - cart, isCartFull vs isShowPopup
  • 엔티티를 다루는 컴포넌트와 훅 - CartItemView, useCart(), useProduct()
  • 엔티티를 다루지 않는 컴포넌트와 훅 - Button, useRoute, useEvent 등
  • 엔티티를 다루는 함수와 그렇지 않은 함수 - calculateCartTotal(cart) vs capaitalize(str)

기본과제

  • Component에서 비즈니스 로직을 분리하기

  • 비즈니스 로직에서 특정 엔티티만 다루는 계산을 분리하기

  • 뷰데이터와 엔티티데이터의 분리에 대한 이해

  • entities -> features -> UI 계층에 대한 이해

  • Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?

  • 주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?

  • 계산함수는 순수함수로 작성이 되었나요?

  • Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?

  • 주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?

  • 계산함수는 순수함수로 작성이 되었나요?

  • 특정 Entitiy만 다루는 함수는 분리되어 있나요?

  • 특정 Entitiy만 다루는 Component와 UI를 다루는 Component는 분리되어 있나요?

  • 데이터 흐름에 맞는 계층구조를 이루고 의존성이 맞게 작성이 되었나요?

심화과제

  • 이번 심화과제는 Context나 Jotai를 사용해서 Props drilling을 없애는 것입니다.

  • 어떤 props는 남겨야 하는지, 어떤 props는 제거해야 하는지에 대한 기준을 세워보세요.

  • Context나 Jotai를 사용하여 상태를 관리하는 방법을 익히고, 이를 통해 컴포넌트 간의 데이터 전달을 효율적으로 처리할 수 있습니다.

  • Context나 Jotai를 사용해서 전역상태관리를 구축했나요?

  • 전역상태관리를 통해 domain custom hook을 적절하게 리팩토링 했나요?

  • 도메인 컴포넌트에 도메인 props는 남기고 props drilling을 유발하는 불필요한 props는 잘 제거했나요?

  • 전체적으로 분리와 재조립이 더 수월해진 결합도가 낮아진 코드가 되었나요?

과제 셀프회고

과제를 진행하기에 앞서 비즈니스 로직과 도메인 로직 구분 기준을 명확히 하는 과정이 필요할 것 같아서 이에 대해 개념을 정리했다.

  • 도메인 로직 : 기술이나 구현 방식과 무관한 순수한 비즈니스 규칙, "무엇"에 대한 정의
  • 비즈니스 로직 : 도메인 로직을 포함한 더 넓은 개념으로, 애플리케이션의 모든 업무 처리 로직을 의미
    • 도메인 로직 + 애플리케이션 흐름 제어
    • 여러 도메인을 조합하여 업무 프로세스 구현
    • "어떻게" 처리할지에 대한 로직

우선, components 폴더를 생성하여 entities - features- UI의 폴더를 생성하고 구조를 분리해 나가기 시작했다.

entities - features- UI 개념

  • entities: 핵심 비즈니스 도메인/데이터를 담당하는 독립적인 구성 요소로 여러 feature에서 재사용 가능
  • features: 특정 사용자 기능 단위의 로직 구현. entities 계층의 데이터와 로직을 조합하여 완성
  • UI: 최종 화면 구성 및 사용자 인터페이스

components/ui/ - 페이지 레이아웃
역할: 전체 페이지 구조만 담당, CartPage, AdminPage는 레이아웃만 구성
특징: 비즈니스 로직 없음, props만 받아서 렌더링

components/features/ - 기능 단위 조합
역할: 여러 entities를 조합해 하나의 기능 완성
예: ProductListFeature는 ProductCard 여러 개를 그리드로 배치
특징: 사용자가 하나의 작업을 완료할 수 있는 단위

components/entities/ - 도메인 객체 표현
역할: 도메인 객체 하나를 화면에 표현
예: ProductCard는 상품 하나를 카드로 표시
특징: props만 받아서 렌더링, 훅 호출 없음

위의 구조로 먼저 ui를 쪼갠 다음 도메인 로직과 비즈니스 로직을 쪼개기 시작하였음.

hooks/ - 상태 관리와 비즈니스 규칙 조합
역할: models/의 순수 함수를 조합하고, 상태를 관리하며, 브라우저와 연결
예: useCart는 models/cart.ts 함수들을 사용하고, useLocalStorage로 저장
특징: 각 훅은 하나의 도메인(장바구니/상품/쿠폰)만 담당


순수함수 리팩토링 중 문제점

// Before: 명시적이지 않은 인자값, 외부 상태 의존
const getMaxApplicableDiscount = useCallback(
  (item: CartItem): number => {
    // cart 상태를 외부에서 참조
    const hasBulkPurchase = cart.some(cartItem => cartItem.quantity >= 10);
    // ...
  },
  [cart] // dependency array로 인한 불필요한 재생성
);

// After: 명시적 입력, 순수 함수
const getMaxApplicableDiscount = (
  item: CartItem,
  cart: CartItem[]
): number => {
  // 모든 필요한 값을 인자로 받음
  // 외부 상태 참조 없음
};

계산 로직 분리

// 계산 전용 순수 함수
const calculateCartTotals = (
  cartItems: CartItem[],
  coupon: Coupon | null
): { totalBeforeDiscount: number; totalAfterDiscount: number } => {
  // 순수 계산 로직만 포함
};

// 훅에서는 계산 결과만 사용
const totals = useMemo(() => {
  return calculateCartTotals(cart, selectedCoupon);
}, [cart, selectedCoupon]);
  • 개선 효과
    테스트 용이성: 외부 상태 모킹 불필요
    명시적 입출력: 함수 시그니처만 보고 동작 파악 가능
    불필요한 메모이제이션 제거: useMemo가 재계산 타이밍을 제어하므로 useCallback 불필요

작업도중 hooks폴더에 각각의 엔티티에 대한 로직들을 넣었다가 계산함수와의 분리를 해야 더 유지보수에 편할 것 같다는 생각이 들어 세부적으로 더 쪼개는 작업을 진행하였음.

더 쪼갠 작업의 결과는 아래와 같다.

models/ - 도메인 비즈니스 로직의 기초
역할: 순수 함수로 도메인 로직 구현
예: models/cart.ts에는 할인 계산, 총액 계산 등이 순수 함수로 정의
특징: React에 의존하지 않아 테스트와 재사용이 쉬움
예시: calculateCartTotal(cart, coupon) → 입력만 주면 결과 반환

tils/hooks/ - 범용 도구 상자
역할: 도메인과 무관한 공통 패턴 제공
예: useLocalStorage(어떤 데이터든 저장), useDebounce(어떤 값이든 디바운스)
특징: 여러 도메인에서 재사용 가능

재사용성

  • models/cart.ts의 함수는 다른 화면(헤더 미니 카트, 통계 페이지)에서도 사용 가능
  • ProductCard는 쇼핑몰, 관리자, 검색 결과 페이지에서 재사용 가능
    ###핵심 원칙
  • 관심사 분리: 로직은 models/, 상태는 hooks/, UI는 components/
  • 단일 책임: 각 파일은 하나의 역할만
  • 의존성 방향: 하위 레이어는 상위 레이어를 모름 (Models는 React를 모름)
  • 재사용성: 하위 레이어일수록 재사용 가능

과제를 하면서 내가 알게된 점, 좋았던 점은 무엇인가요?

  • fsd 설계에 대한 개념 학습
  • 함수형 프로그래밍 개념 학습 및 작성법
  • 어떤 구조로 설계를 하고 함수를 쪼개야 유지보수와 재사용성 측면에서 좋은지에 대한 많은 생각을 하게되는 시간을 가졌음

이번 과제에서 내가 제일 신경 쓴 부분은 무엇인가요?

이번 과제를 통해 앞으로 해보고 싶은게 있다면 알려주세요!

개인적인 시간이 부족하여 상태 관리 라이브러리를 써보지 못한 것이 아쉽고 시간이 난다면 zustand는 사용경험이 있었기 때문에 jotail을 활용하여 상태 관리 로직도 작성해 보고 싶다.

리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문 편하게 남겨주세요 :)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant