Skip to content

[Step2.1] cactus: Context API 적용하기 - #4

Open
ehlung wants to merge 14 commits into
cactus-adv-1from
cactus-adv-2.1
Open

[Step2.1] cactus: Context API 적용하기#4
ehlung wants to merge 14 commits into
cactus-adv-1from
cactus-adv-2.1

Conversation

@ehlung

@ehlung ehlung commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

개인 목표 달성 여부

  • 현재 코드에서 props drilling이 어디서 발생하는지 직접 찾아보고, Context API가 이를 어떻게 해소하는지 체감한다.
  • createContext, Provider, useContext의 역할과 데이터 흐름을 이해하고, 세 요소가 어떻게 연결되는지 스스로 설명할 수 있는 수준으로 익힌다.
  • Context API를 쓰는 것이 적절한 상황과 그렇지 않은 상황(trade-off)을 이해하고, 그 판단 근거를 PR에 직접 서술한다.
  • 컴포넌트와 Context 간의 관계를 도식화해보며 데이터 흐름을 시각적으로 이해하는 경험을 쌓는다.

리뷰어에게

특히 봐줬으면 하는 부분, 확신이 없는 코드, 논의하고 싶은 것

  • RestaurantContextModalContext로 나눈 분리 기준이 적절한지 피드백 부탁드립니다.
  • ModalContextRestaurantContext에 단방향으로 의존하는 구조가 적절한지 함께 논의하면 좋을 것 같습니다.

Context API를 사용한 이유와 trade-off

왜 Context API를 선택했는가

기존 코드에서 props drilling이 심각하게 발생하지는 않았습니다. 컴포넌트 트리가 얕아서 App의 모든 자식이 App에서 직접 props를 받고 있었고, 중간에 전달만 하는 컴포넌트가 없었습니다.

대신 다른 문제가 있었습니다. App.jsx가 상태 3개, 핸들러 6개, 필터 계산 로직을 전부 들고 있어 역할이 지나치게 집중된 상태였습니다. 상태와 함수를 관심사 기준으로 나눠 Context로 분리하는 것이 적합하다고 판단했습니다.

  • RestaurantContext — 레스토랑 목록, 카테고리 필터처럼 데이터 자체와 관련된 상태
  • ModalContext — 모달 열림/닫힘, 선택된 레스토랑처럼 UI 상태

trade-off

Context API 도입 후
장점 App이 상태 전달 책임에서 벗어나 레이아웃 구조에만 집중할 수 있게 됐다. 컴포넌트가 필요한 값을 직접 꺼내 쓴다.
단점 Context에 의존하는 컴포넌트는 해당 Provider 트리 안에서만 사용 가능해 재사용성이 제한된다. Context value가 변경되면 해당 Context를 구독하는 모든 컴포넌트가 리렌더링된다.

Context API와 컴포넌트 관계 도식

context-diagram

Summary by CodeRabbit

  • New Features

    • 전역 상태 관리가 Context 기반으로 전환되어, 음식점 목록 필터링과 모달 제어가 더 일관되게 동작합니다.
    • 음식점 추가 및 상세 보기 흐름이 앱 전반에서 연결되도록 개선되었습니다.
  • Documentation

    • Context API, Zustand, TanStack Query 실습용 안내 문서가 추가/갱신되었습니다.
    • 기존 메인 안내 문서는 전역 상태 관리 중심 내용으로 새로 정리되었습니다.
  • Bug Fixes

    • props 전달을 줄여 상태 꼬임과 중복 전달 문제를 완화했습니다.
    • 빈 컨텍스트 사용 시 오류를 안내하도록 개선했습니다.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 2e459eac-0f30-43c1-a33d-888b50f0ddd1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

전역 상태를 Context Provider와 커스텀 훅으로 분리하고, 앱과 레스토랑/모달 컴포넌트가 props 대신 컨텍스트를 직접 사용하도록 바꿨다. 샘플 데이터와 상태관리 학습 README들도 함께 갱신됐다.

Changes

Context API 상태관리 전환

Layer / File(s) Summary
Provider와 훅
src/context/RestaurantContext.jsx, src/context/ModalContext.jsx, src/context/useRestaurantContext.js, src/context/useModalContext.js, src/main.jsx
RestaurantContextModalContext가 추가되고, null 방어 훅과 Provider 기반 루트 래핑이 더해졌다.
식당 UI 전환
src/App.jsx, src/components/CategoryFilter/CategoryFilter.jsx, src/components/Header/Header.jsx, src/components/RestaurantList/RestaurantList.jsx, db.json
App과 주요 식당 UI 컴포넌트가 props 대신 컨텍스트를 직접 사용하도록 바뀌고, 식당 샘플 데이터 2개가 추가됐다.
모달 컴포넌트
src/components/Modal/AddRestaurantModal.jsx, src/components/Modal/RestaurantDetailModal.jsx
AddRestaurantModalRestaurantDetailModal이 모달 상태와 핸들러를 props가 아닌 컨텍스트에서 읽도록 바뀌었다.
README 갱신
README.md, 02-state-management-tools/2.1-ContextAPI/README.md, 02-state-management-tools/2.2-Zustand/README.md, 02-state-management-tools/2.3-TanStack Query/README.md
루트 README와 상태관리 실습 README들이 Context API, Zustand, TanStack Query 내용으로 재작성되거나 추가됐다.

Sequence Diagram(s)

sequenceDiagram
  participant RestaurantProvider
  participant ModalProvider
  participant App
  participant Header
  participant AddRestaurantModal
  participant ModalContext
  participant RestaurantContext
  RestaurantProvider->>ModalProvider: render children
  ModalProvider->>App: render App
  App->>Header: render add button
  Header->>ModalContext: handleAddModalOpen()
  App->>AddRestaurantModal: render when isAddModalOpen
  AddRestaurantModal->>ModalContext: handleFormSubmit(newRestaurant)
  ModalContext->>RestaurantContext: registerRestaurant(newRestaurant)
  ModalContext->>AddRestaurantModal: handleAddModalClose()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

나는 토끼, 귀 쫑긋 Context를 배웠다 🐇
props 들판은 살짝 뒤로 폴짝
Provider 당근밭에 상태가 자라나고
모달 문이 열리면 리스트도 반짝
냠냠, 오늘의 홉은 아주 깔끔해!


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands.

@ehlung ehlung self-assigned this Jun 26, 2026
@ehlung
ehlung requested a review from meteorqz6 June 26, 2026 20:29
@pair-study pair-study deleted a comment from coderabbitai Bot Jun 26, 2026
Comment thread src/context/ModalContext.jsx Outdated
export const ModalContext = createContext(null);

export function ModalProvider({ children }) {
const { registerRestaurant } = useRestaurantContext();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[논의]
현재 ModalProvider 내부에서 useRestaurantContext()를 호출하고 있는데 이로 인해서 2가지 문제가 생긴다고 생각합니다.

  1. Provider 중첩 순서가 암묵적인 제약이 된다.
  2. ModalProvider를 단독으로 테스트할 수 없다.

이를 개선하기 위한 방법으로는 registerRestaurant를 ModalProvider의 prop으로 받도록 변경하면 의존성이 명시적으로 드러나고 두 Context가 독립적으로 존재할 수 있다고 생각합니다.

예령님은 어떻게 생각하시는지 궁금합니다. 또한 코드를 이렇게 작성하게 된 이유가 있다면 공유해주세요!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Provider 중첩 순서 문제는 저도 인지하고 있었는데, 순환 참조가 생기지 않도록 의존 방향만 단방향으로 고정하면 된다고 생각하고 넘어갔습니다. prop으로 받아서 의존성을 명시적으로 드러내는 방법은 생각 못 했는데 좋은 방법인 것 같아요!
다만 현재 ModalContext 자체를 제거하는 쪽으로 리팩토링을 계획중입니다. UI 상태는 App의 직접 자식들에게만 필요한 상태라 Context에 올릴 이유가 없었는데, props drilling 제거가 목표가 되면서 과하게 올린 게 있었다는 판단이 들었습니다! 그래서 UI 상태는 App 로컬로 되돌리고 props로 내려줄 예정입니다. 이렇게 되면 Context 간 의존 자체가 사라져서 지적해주신 문제가 근본적으로 해결될 것 같습니다.
제가 구현한 방향 안에서 문제 해결 방법을 고민해주셔서 감사합니다!

Comment thread src/context/useModalContext.js Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[배움]
저는 Context 사용부에서 컴포넌트마다 직접 useContext를 사용했는데 별도의 커스텀 훅을 사용하면 이점이 명확하다는 생각이 드네요!

  1. null 체크를 컴포넌트마다 반복하지 않아도 된다.
  2. Context를 내부 구현으로 숨겨서, 컴포넌트가 상태 관리의 구현 방식에 의존하지 않도록 할 수 있다.

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.

2 participants