붕어빵 가게 메뉴판 설계하기: 기획자를 위한 리액트 기능 단위 설계법

붕어빵 가게 메뉴판 설계하기: 기획자를 위한 리액트 기능 단위 설계법

붕어빵 가게 메뉴판 설계하기: 기획자를 위한 리액트 기능 단위 설계법

보통 기획자는 화면을 ‘페이지’ 단위로 생각합니다. “1번 페이지(홈)를 만들고, 2번 페이지(상세)를 만들자” 같은 방식이죠.

하지만 리액트(React) 개발자는 화면을 ‘컴포넌트의 조립’으로 봅니다. 이 시각 차이를 줄이지 못하면, 기획서의 양은 방대해지는데 개발 효율은 떨어지는 악순환이 생깁니다.

오늘은 붕어빵 가게의 메뉴판을 설계하며, 리액트식 사고방식인 Thinking in React를 실무 기획에 어떻게 적용할지 정리해 보겠습니다. 🐟

핵심 요약 (오늘 가져갈 3가지)

  • Decomposition: 페이지를 ‘부품’으로 쪼개기
  • Hierarchy: 부품의 가족 관계(계층) 정하기
  • Reusability: 같은 부품을 다른 메뉴에도 재사용하기

붕어빵 가게 메뉴판 설계하기

1. 페이지 중심 기획이 리액트에서 흔들리는 이유

페이지 단위 기획은 “화면을 그려서 전달”하기에는 편하지만, 리액트 환경에서는 개발자가 가장 먼저 이렇게 묻습니다.

  • “이 화면에서 재사용 가능한 영역은 무엇인가요?”
  • “이 데이터는 어디서 관리하고(State), 어디로 내려가나요(Props)?”
  • “나중에 기능이 늘어나면 이 구조는 확장 가능한가요?”

즉, 리액트 협업에서는 페이지가 아니라 기능 단위(컴포넌트 + 데이터 흐름)로 설명할수록 질문이 줄고 속도가 빨라집니다.

2. 1) 페이지가 아니라 ‘부품’으로 쪼개기(Decomposition)

붕어빵 가게 메뉴판 기획을 시작해 봅시다. 페이지 전체를 하나로 그리는 대신, 화면을 구성하는 독립적인 부품이 무엇인지부터 찾아냅니다.

기획자의 기존 방식 vs 리액트적 사고

  • 기존 방식: “메뉴판 페이지 하나 그려주세요.”
  • 리액트적 사고:
    • 상단에는 가게 이름을 알리는 [헤더]
    • 중간에는 붕어빵 종류를 보여주는 [메뉴 리스트]
    • 그 안에는 개별 붕어빵의 이름/가격이 담긴 [메뉴 아이템]이 반복

💡 핵심 포인트
화면을 가장 작은 단위까지 쪼개 보세요. 이렇게 쪼개진 부품은 다른 페이지(예: 장바구니/주문 내역)에서도 그대로 재사용될 수 있습니다.

메뉴판을 부품으로 나눈 예시(텍스트 도식)

[MenuBoardPage]
  ├─ [Header]
  ├─ [MenuList]
  │     ├─ [MenuItem] (팥 붕어빵)
  │     ├─ [MenuItem] (슈크림 붕어빵)
  │     └─ [MenuItem] (잡채 붕어빵)
  └─ [CartSummary] (선택)
        

3. 2) 정보의 계층 구조 만들기(Hierarchy)

부품을 다 찾았다면, 이제 누가 누구를 품고 있는지 ‘가족 관계도(계층)’를 정해야 합니다. 계층이 정리되면, 데이터가 어디서 시작되어야 하는지 감이 딱 잡힙니다.

가족 관계도 예시

  • 최상위: 메뉴판(App / MenuBoardPage)
  • 중간: 메뉴 리스트(MenuList)
  • 최하위: 메뉴 아이템(MenuItem) 반복

기획적 시사점: 데이터의 시작점이 보인다

예를 들어 “붕어빵 가격 데이터”는 메뉴판 전체가 들고 있다가, 각 아이템에게 Props로 나눠줘야 합니다. 반대로 “현재 선택된 메뉴”처럼 사용자 행동으로 바뀌는 값은 어디까지 영향을 주는지에 따라 State 위치가 결정됩니다.

실무 팁: ‘영향 범위’로 State 위치를 결정하기

  • 선택 값이 메뉴 아이템 하나만 바뀐다 → MenuItem 로컬 State 가능
  • 선택 값이 리스트 전체에 영향을 준다 → MenuList에서 State 관리
  • 선택 값이 헤더/장바구니 요약까지 영향을 준다 → 상위(MenuBoardPage/App)로 State 끌어올리기

4. 3) 재사용성을 고려한 설계(Reusability)

붕어빵 가게가 대박이 나서 ‘음료 메뉴판’을 추가하기로 했다고 해봅시다. 이때 리액트적인 기획자는 “똑같은 화면을 새로 그리는” 실수를 하지 않습니다.

나쁜 기획 vs 리액트적 기획

  • 나쁜 기획: “음료 전용 메뉴판 페이지를 새로 기획합니다.” (개발 공수 증가)
  • 리액트적 기획: “기존 [MenuList] 컴포넌트를 재사용하고, 내용물(Props)만 붕어빵에서 커피로 바꿔서 보여주세요.”

한 번 잘 만든 컴포넌트 하나가 열 페이지 부럽지 않게 됩니다. (메뉴판이 아니라 “부품 카탈로그”가 쌓이는 느낌이에요) 📚🐟

재사용성을 높이기 위한 기획 체크 포인트

  • 이 부품은 다른 화면에서도 같은 형태로 쓰일까?
  • 바뀌는 건 무엇이고(Props), 변하지 않는 구조는 무엇인가?
  • 이 부품에 들어갈 문구/아이콘/정렬 방식은 옵션화 가능한가?

5. 추가 예시) 메뉴판을 ‘서비스’로 확장하면 이렇게 보입니다: 장바구니·주문·결제 컴포넌트 트리

“메뉴판 화면만” 쪼개는 걸 넘어서 실제 서비스처럼 장바구니 → 주문 → 결제까지 이어지면 컴포넌트 단위 설계가 왜 중요한지 더 또렷해집니다. 아래는 붕어빵 가게를 앱으로 만들었을 때의 대표적인 컴포넌트 트리 예시입니다.

1) 전체 앱 레벨 트리(레이아웃 + 기능 묶음)

[App]
  ├─ [AppLayout]
  │    ├─ [Header]
  │    │    ├─ [Logo]
  │    │    ├─ [SearchBar] (선택)
  │    │    └─ [CartBadge] (장바구니 수량)
  │    ├─ [GlobalToast] (공통 알림)
  │    └─ [Footer] (선택)
  │
  └─ [Routes]
       ├─ [MenuBoardPage]   (메뉴판)
       ├─ [CartPage]        (장바구니)
       ├─ [OrderPage]       (주문서)
       └─ [CheckoutPage]    (결제)
        

2) 메뉴판(MenuBoardPage) 내부 트리

[MenuBoardPage]
  ├─ [CategoryTabs] (팥/슈크림/잡채/음료)
  ├─ [MenuList]
  │    ├─ [MenuItem] x N
  │    │     ├─ [ItemThumbnail]
  │    │     ├─ [ItemTitle]
  │    │     ├─ [ItemPrice]
  │    │     └─ [AddToCartButton]
  │    └─ (상태 분기) [LoadingSkeleton] / [EmptyState] / [ErrorState]
  └─ [CartSummaryBar] (하단 고정, 선택)
        

3) 장바구니(CartPage) 내부 트리

[CartPage]
  ├─ [PageTitle]
  ├─ [CartList]
  │    ├─ [CartItemRow] x N
  │    │     ├─ [ItemThumbnail] (MenuItem과 재사용 가능)
  │    │     ├─ [ItemTitle]
  │    │     ├─ [QuantityStepper] (수량 +/-)
  │    │     ├─ [ItemPrice]
  │    │     └─ [RemoveButton]
  │    └─ (상태 분기) [LoadingSkeleton] / [EmptyState] / [ErrorState]
  └─ [OrderSummary]
       ├─ [PriceBreakdown] (합계/할인/배송)
       └─ [PrimaryButton] (주문하기)
        

4) 주문(OrderPage) 내부 트리

[OrderPage]
  ├─ [OrderSteps] (장바구니 > 주문 > 결제)
  ├─ [UserInfoSection]
  │    ├─ [TextField] (이름)
  │    ├─ [TextField] (연락처)
  │    └─ [AddressForm] (선택)
  ├─ [DeliverySection] (선택)
  │    ├─ [RadioGroup] (수령 방식)
  │    └─ [TimePicker] (선택)
  ├─ [OrderItemsPreview] (장바구니 아이템 요약)
  └─ [PrimaryButton] (결제하기)
        

5) 결제(CheckoutPage) 내부 트리

[CheckoutPage]
  ├─ [PaymentMethodSelector] (카드/간편결제/계좌)
  ├─ [PaymentForm]
  ├─ [AgreementSection] (필수 약관 동의)
  ├─ [PrimaryButton] (결제 요청)
  └─ (상태 분기)
       ├─ [ProcessingState] (결제 진행 중 로딩)
       ├─ [PaymentSuccessPage]
       └─ [PaymentErrorPage] (재시도/다른 수단/고객센터)
        

기획적 포인트: “공통 컴포넌트” 후보가 눈에 보입니다

  • 공통: Header, CartBadge, PrimaryButton, TextField, LoadingSkeleton, EmptyState, ErrorState, Toast
  • 화면 전용: MenuBoardPage 전용 CategoryTabs, CheckoutPage 전용 PaymentForm
  • 재사용 가능하지만 변형 필요: ItemThumbnail/ItemTitle/ItemPrice(표시 방식만 다름)

💡 실무 Tip
기획서에 이 트리를 1장만 넣어도 개발자는 “무엇을 공통으로 빼고, 무엇을 화면 전용으로 둘지”를 빠르게 결정합니다. 그 결과, 질문은 줄고 설계는 빨라집니다.

6. 1장 요약: 붕어빵 가게 앱 ‘기능 단위 설계’ 한눈에 보기(Thinking in React)

페이지 중심이 아니라 컴포넌트(부품) 조립으로 화면을 설계하면 ‘중복’이 줄고 ‘재사용’이 늘어 기획서는 가벼워지고 개발은 빨라집니다. 아래 도식은 붕어빵 가게 서비스를 메뉴판 → 장바구니 → 주문 → 결제 흐름으로 확장했을 때의 대표 구조입니다.

컴포넌트 트리(서비스 전체 구조 도식)

[App]
  ├─ [AppLayout]
  │    ├─ [Header] ─ [CartBadge]
  │    ├─ [GlobalToast]
  │    └─ [Footer]
  │
  └─ [Routes]
       ├─ [MenuBoardPage]
       │     ├─ [CategoryTabs]
       │     └─ [MenuList] ─ [MenuItem] x N ─ [AddToCartButton]
       │           └─ (상태) [LoadingSkeleton] / [EmptyState] / [ErrorState]
       │
       ├─ [CartPage]
       │     ├─ [CartList] ─ [CartItemRow] x N ─ [QuantityStepper]
       │     └─ [OrderSummary] ─ [PrimaryButton]
       │           └─ (상태) [LoadingSkeleton] / [EmptyState] / [ErrorState]
       │
       ├─ [OrderPage]
       │     ├─ [OrderSteps]
       │     ├─ [UserInfoSection] ─ [TextField]
       │     └─ [PrimaryButton]
       │
       └─ [CheckoutPage]
             ├─ [PaymentMethodSelector]
             ├─ [PaymentForm]
             ├─ [AgreementSection]
             └─ (상태) [ProcessingState] / [PaymentSuccessPage] / [PaymentErrorPage]
        

핵심 설계 포인트 5가지(기획서 기준)

  1. 페이지를 ‘부품’으로 쪼갠다(Decomposition).
    메뉴판/장바구니/결제 화면을 통째로 그리기보다, 헤더/리스트/아이템/버튼처럼 독립 부품을 먼저 정의한다.
  2. 계층(Hierarchy)을 먼저 정하면 데이터 흐름이 보인다.
    어떤 데이터가 상위에서 시작되어 하위로 Props로 내려가는지, 어떤 값이 State로 관리되어야 하는지 판단이 빨라진다.
  3. 공통 컴포넌트 후보를 조기에 박아둔다.
    예: Header, PrimaryButton, TextField, LoadingSkeleton, EmptyState, ErrorState, Toast는 재사용 가능성이 높다.
  4. 상태 분기(Loading/Empty/Error)는 ‘화면 공통 뼈대’로 본다.
    목록형 화면(MenuList/CartList)에는 성공뿐 아니라 로딩/0건/실패 UI를 세트로 설계해 질문을 줄인다.
  5. 확장 시 “Props만 바꾸고 구조는 재사용”을 목표로 한다.
    붕어빵 메뉴판과 음료 메뉴판처럼, 같은 리스트 구조를 재사용하고 데이터/문구만 바꾸면 공수와 QA가 줄어든다.

💡 한 줄 결론
“페이지를 그린다”가 아니라 “부품을 조립한다”로 사고를 바꾸면, 기획서가 개발자의 ‘설계 지도’가 됩니다.

7. 🛠️ 기획자를 위한 리액트 설계 체크리스트

아래 표는 기획서를 “페이지”가 아니라 “기능 단위”로 바꿔주는 질문들입니다. 이 체크리스트만 통과해도 개발자 질문이 확 줄어듭니다.

리액트 기능 단위 설계 체크리스트(기획자용)
질문 기획자가 해야 할 일 개발자의 반응(기대 효과)
중복되는 UI가 있는가? 공통 컴포넌트(버튼/입력창/카드/리스트) 정의 “코드 재사용성이 좋아지네요!”
데이터가 어디서 쓰이는가? 데이터가 영향을 미치는 범위(계층) 정의 “상태 관리가 명확해졌어요.”
확장 가능성이 있는가? 추가될 유사 기능(음료/세트/토핑) 고려 “설계 변경 없이 바로 대응 가능합니다.”

8. 기획서에 바로 쓰는 문장 템플릿(복붙용)

Decomposition(부품 분해) 템플릿

  • “이 화면은 [헤더] + [리스트] + [아이템] 조합이며, [아이템]은 반복됩니다.”
  • “반복되는 UI는 공통 컴포넌트 후보로 정의합니다(버튼/카드/입력창 등).”

Hierarchy(계층/데이터 흐름) 템플릿

  • “데이터는 상위에서 관리하고, 하위 컴포넌트로 Props로 전달합니다.”
  • “사용자 인터랙션으로 변하는 값은 영향 범위에 따라 State 위치를 결정합니다(로컬/리스트/상위).”

Reusability(재사용) 템플릿

  • “[MenuList]는 구조는 유지하고, 데이터(Props)만 교체해 [붕어빵/음료] 모두에 재사용합니다.”
  • “문구/아이콘/정렬은 옵션화해 같은 컴포넌트를 다양한 화면에서 활용합니다.”

9. 마치며: 기획서가 가벼워지면 서비스는 단단해집니다

‘리액트적으로 생각하기(Thinking in React)’는 결국 불필요한 중복을 줄이고 효율을 극대화하는 과정입니다. 페이지 중심의 기획서가 ‘레고 설명서’처럼 기능 단위로 설계될 때, 개발자와 기획자 사이의 오해는 줄고 서비스는 훨씬 빠르게 성장할 수 있습니다.

이제 화면을 설계할 때 붕어빵 메뉴판을 떠올려 보세요. “이 부품을 어디에 또 쓸 수 있을까?” 이 질문 하나가 여러분의 기획력을 바꿔놓을 겁니다. 🧩🐟

10. 자주 묻는 질문(FAQ)

Q Thinking in React는 기획자에게 왜 필요한가요?

A 리액트 팀은 화면을 페이지가 아니라 컴포넌트 조립으로 구현합니다. 기능 단위로 설계하면 질문과 재작업이 줄고 개발 속도가 빨라집니다.

Q 기획서에서 컴포넌트 이름까지 정해야 하나요?

A 이름을 확정할 필요는 없지만, 재사용 의도(공통 요소)와 데이터/상태 범위(계층)는 명확히 적는 것이 효과적입니다.

Q 재사용성을 높이면 무엇이 좋아지나요?

A 중복 구현이 줄어 공수가 감소하고, 공통 컴포넌트 수정으로 여러 화면이 함께 개선되어 유지보수가 쉬워집니다.

11. 참고 자료