Skip to content

[Step2.1] hippo: Context API 적용하기 - #3

Open
meteorqz6 wants to merge 6 commits into
hippo-adv-1from
hippo-adv-2.1
Open

[Step2.1] hippo: Context API 적용하기#3
meteorqz6 wants to merge 6 commits into
hippo-adv-1from
hippo-adv-2.1

Conversation

@meteorqz6

@meteorqz6 meteorqz6 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

개인 목표 달성 여부

  • createContext, Provider, useContext 세 가지 개념의 역할을 명확히 이해하고 직접 구현한다.
  • props drilling이 발생하는 지점을 코드에서 직접 파악하고 Context로 해결하는 경험을 쌓는다.
  • UI 상태와 데이터 상태를 구분해서 Context 적용 범위를 스스로 판단하는 능력을 기른다.

리뷰어에게

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

  • 왜 Context API를 선택했고, trade-off가 무엇인지 함께 논의하면 좋을 것 같습니다.

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

왜 Context API를 선택했는가

기존 구조에서 restaurants, addRestaurant, isLoading, error는 모두 AppuseRestaurants 훅을 직접 호출해서 관리하고 있었습니다. 이 데이터들을 필요로 하는 컴포넌트가 RestaurantList, AddRestaurantModal로 분산되어 있어 App이 중간 전달자 역할만 하는 구조였습니다.

특히 addRestaurantuseRestaurantsApphandleRestaurantSubmitAddRestaurantModal로 이어지는 경로를 거쳐야 했는데, App은 실질적인 처리 없이 전달만 하고 있었습니다. 이처럼 여러 컴포넌트에서 공유되는 데이터 도메인(서버 데이터 + 관련 액션) 을 Context로 분리하는 것이 적합하다고 판단했습니다.

trade-off

Context API 도입 후
장점 App이 데이터 전달 책임에서 벗어나 UI 상태만 관리한다. 컴포넌트가 필요한 데이터를 직접 구독한다.
단점 Context value가 변경되면 해당 Context를 구독하는 모든 컴포넌트가 리렌더링된다. 현재는 restaurants, addRestaurant, isLoading, error를 하나의 객체로 묶어 전달하므로, 어느 하나만 바뀌어도 모든 구독 컴포넌트가 리렌더링될 수 있다.
선택하지 않은 것 selectedCategory 같은 UI 상태는 App이 계속 관리한다. 특정 화면의 인터랙션 상태는 Context보다 로컬 state가 더 자연스럽다고 판단했다.

Context API와 컴포넌트 관계 도식

image

@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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Free

Run ID: 5d980cef-ea75-4244-9961-30f8287e0d73

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

문서가 Context API 전역 상태관리 과제로 갱신되고, RestaurantsContext/RestaurantsProvider가 추가되었습니다. App은 Provider로 감싸지고, RestaurantListAddRestaurantModal은 Context를 직접 사용하도록 바뀌었습니다. 일부 컴포넌트는 선언 위치만 재배치되었습니다.

Changes

Context API 전환과 문서 갱신

Layer / File(s) Summary
문서 갱신
02-state-management-tools/2.1-ContextAPI/READEME.md, README.md
Context API 과제 설명, 학습 목표, 구현 체크리스트, 개념 정리, 해결 과정, 리팩토링 설명으로 문서가 다시 구성됩니다.
Context provider
src/context/RestaurantsContext.jsx
RestaurantsContextRestaurantsProvider가 추가되어 useRestaurants()restaurants, addRestaurant, isLoading, error를 context value로 노출합니다.
App wiring
src/App.jsx
AppRestaurantsProvider로 감싸지고, 목록 데이터 전달과 AddRestaurantModalonSubmit prop 전달이 제거됩니다.
Context consumers
src/components/RestaurantList.jsx, src/components/AddRestaurantModal.jsx
RestaurantListRestaurantsContext에서 목록 상태를 읽고 selectedCategory로 필터링하며, AddRestaurantModal이 context의 addRestaurant를 직접 호출해 성공 시 닫고 실패 시 알림을 표시합니다.
Declaration reorders
src/components/CategoryFilter.jsx, src/components/Header.jsx, src/components/Modal.jsx, src/components/RestaurantDetailModal.jsx, src/components/RestaurantList.jsx
컴포넌트 선언과 스타일 선언의 위치가 바뀌며 렌더링 출력은 유지됩니다.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AddRestaurantModal
  participant RestaurantsContext
  User->>AddRestaurantModal: 폼 제출
  AddRestaurantModal->>RestaurantsContext: addRestaurant({ category, name, description })
  RestaurantsContext-->>AddRestaurantModal: 추가 완료
  AddRestaurantModal->>AddRestaurantModal: onClose()
Loading

Estimated Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes


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.

@meteorqz6

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@meteorqz6 meteorqz6 self-assigned this Jun 26, 2026
@meteorqz6 meteorqz6 changed the title Hippo adv 2.1 [Step2.1] hippo: Context API 적용하기 Jun 26, 2026
@ehlung
ehlung self-requested a review June 26, 2026 20:29
Comment thread README.md
### React 18 vs React 19 Provider 문법 차이

기존 styled-component를 상속해서 스타일을 추가할 수 있다.
React 19부터는 Context 객체 자체를 Provider로 사용할 수 있다. 공식문서가 React 19 기준으로 업데이트되었으므로 버전 확인이 필요하다.

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.

[배움]
리액트 버전에 따른 문법 차이가 있는 줄 몰랐는데 덕분에 알게되었습니다. Provider를 사용할 때 버전 확인을 할 필요가 있겠네요!

Comment thread src/components/AddRestaurantModal.jsx Outdated
const [category, setCategory] = useState("");
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const { addRestaurant } = useContext(RestaurantsContext);

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.

[제안]
createContext(null)로 초기화해서 Provider 없이 useContext를 호출하면 null을 반환하도록 설정한 건 좋은 것 같아요. 근데 지금은 그냥 TypeError 기본 에러가 뜨는데, 메시지만 봐서는 Provider가 빠진 게 원인인지 바로 알기 어렵다고 생각해요!

export function useRestaurantsContext() {
  const context = useContext(RestaurantsContext);
  if (context === null) throw new Error("RestaurantsProvider 내부에서만 사용할 수 있습니다.");
  return 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.

네 리팩토링에 적용해보도록 하겠습니다

Comment thread src/components/RestaurantList.jsx Outdated
selectedCategory,
onRestaurantClick,
}) {
const { restaurants, isLoading, error } = useContext(RestaurantsContext);

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.

[배움]
isLoading, error를 App이 아닌 RestaurantList에서 처리한 게 처음엔 의아했는데, 읽다 보니 데이터를 쓰는 컴포넌트가 그 데이터의 상태도 함께 처리한다는 판단인 것 같아서 좋은 방식인 것 같아요. restaurants를 실제로 보여주는 건 RestaurantList니까, 서버가 실패했을 때 어떻게 표시할지도 RestaurantList가 결정하는 게 응집도 측면에서 맞는 것 같아요. 이게 나중에 TanStack Query에서 const { data, isLoading, error } = useQuery()로 데이터와 상태를 한 곳에서 처리하는 패턴이랑 같은 방향이라는 것도 알게 되어서 좋은 공부가 되었습니다!

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