Skip to content

[Step5] cactus - API 요청과 비동기 처리 - #10

Open
ehlung wants to merge 10 commits into
cactus-step4from
cactus-step5
Open

[Step5] cactus - API 요청과 비동기 처리#10
ehlung wants to merge 10 commits into
cactus-step4from
cactus-step5

Conversation

@ehlung

@ehlung ehlung commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

개인 목표 달성 여부

  • side effect와 useEffect 이해
  • fetch를 통한 API 연동 흐름 이해 (GET/POST)
  • useEffect 의존성 배열 이해

리뷰어에게

  • 처음엔 의존성 배열을 []로만 뒀다가 과거 코드 리뷰를 보고 useCallback을 적용해 수정했습니다. 이 방향이 적절한지 피드백 부탁드립니다.
  • POST 후 race condition 방지를 위해 await fetchRestaurants()로 순서를 보장했는데, 스터디 때 다른 방법도 함께 알아보면 좋을 것 같습니다.

Summary by CodeRabbit

  • Documentation

    • API 연동 및 Side Effect 처리 관련 학습 가이드 추가
    • useEffect, 의존성 배열, 비동기 함수 처리 방법 문서 구성
  • New Features

    • REST API를 통한 레스토랑 목록 동적 조회 기능 구현
    • 모달에서 새 레스토랑 추가 후 목록 자동 갱신
  • Refactor

    • 정적 더미 데이터 기반 처리에서 API 기반 동적 데이터 처리로 전환

@ehlung
ehlung requested a review from meteorqz6 June 14, 2026 11:26
@ehlung ehlung self-assigned this Jun 14, 2026
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

src/App.jsx에서 로컬 더미 데이터를 제거하고 useCallback/useEffect/fetch를 사용해 http://localhost:3000/restaurants REST API와 연동하도록 변경한다. 루트 README.md를 Step 5 학습 문서로 전면 교체하고, 05-effects/README.md를 신규 구성한다.

Changes

REST API 연동 및 학습 문서 교체

Layer / File(s) Summary
App.jsx — fetch·useEffect·useCallback 연동
src/App.jsx
useCallback/useEffect import를 추가하고, newRestaurants 상태와 GET fetchRestaurants를 정의해 마운트 시 자동 호출한다. handleFormSubmitasync로 전환해 POST 생성 후 fetchRestaurants를 재호출하고 모달을 닫는다.
루트 README Step 5 학습 문서 교체
README.md
Step 4 내용을 제거하고 Step 5 기준으로 전면 교체한다. 구현 기능 목록, useEffect 실행 규칙, fetch-async-await 흐름, useCallback 참조 안정화, 고민과 해결 과정, 리팩토링 변경점 및 과거 코드 비교를 포함한다.
05-effects README 신규 구성
05-effects/README.md, 04-form/README.md
05-effects/README.md를 새로 구성해 요구사항·키워드·진행 가이드, json-server 사용법과 GET/POST 예시, React 공식 문서 참고 링크를 추가한다. 04-form/README.md의 기존 내용은 제거된다.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 토끼가 API를 두드렸어요,
fetch로 당근 목록을 불러왔죠.
useEffect가 딱 한 번 실행되고,
useCallback이 참조를 꼭 붙잡아요.
POST 후 await, 순서도 완벽! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경사항인 API 요청과 비동기 처리(useEffect)를 명확하게 요약하고 있습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cactus-step5

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

@ehlung
ehlung changed the base branch from main to cactus-step4 June 14, 2026 11:26
@ehlung ehlung changed the title Step5: API 연동하기 (feat. useEffect) Step5: API 요청과 비동기 처리 Jun 14, 2026
@ehlung ehlung changed the title Step5: API 요청과 비동기 처리 Step5: cactus - API 요청과 비동기 처리 Jun 14, 2026
@ehlung ehlung changed the title Step5: cactus - API 요청과 비동기 처리 [Step5] cactus - API 요청과 비동기 처리 Jun 14, 2026
Comment thread src/App.jsx Outdated
{ id: crypto.randomUUID(), ...newRestaurant },
]);
const fetchRestaurants = useCallback(async () => {
const response = await fetch("http://localhost:3000/restaurants");

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.

[제안]
http://localhost:3000 BASE_URL의 경우, 상수로 추출해서 한 곳에서 관리를 하면 좋을 것 같습니다. 여러 파일에 하드코딩되어 있으면 API 주소가 변경될 때마다 일일이 검색해서 수정해야 하기 때문에 한 곳에서 관리하면 수정 범위를 최소화할 수 있습니다!

@meteorqz6

Copy link
Copy Markdown
Contributor

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 14, 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 141-151: The comparison table in README.md (lines 141-151) has the
"과거 코드" (past code) and "현재 코드" (current code) columns reversed, causing the
descriptions of useCallback/dependency array and id generation to contradict the
actual current src/App.jsx implementation. Swap the column contents or re-label
the columns so that "현재 코드" accurately describes what is actually implemented in
the current App.jsx code (general async function without useCallback and empty
dependency array for fetchRestaurants, and server-side id generation). Also
correct the same backwards description in the id generation section that follows
to ensure learners understand the actual evolution and current state of the
code.

In `@src/App.jsx`:
- Around line 15-31: The current code treats API failures as successes because
fetch does not throw exceptions on 4xx/5xx status codes. The fetchRestaurants
function lacks error handling and does not check response.ok before processing
data, which can cause unhandled rejections on mount. The handleFormSubmit
function does not verify the POST succeeded before refetching restaurants. Wrap
both fetchRestaurants and handleFormSubmit in try/catch blocks, add response.ok
checks after each fetch call to verify success, and only proceed with state
updates and subsequent operations when the response is successful. Remove calls
to setNewRestaurants and fetchRestaurants from the error paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 64265a6d-9ff3-414a-8bf2-0e0aef25727c

📥 Commits

Reviewing files that changed from the base of the PR and between 84774ad and bbbf4be.

📒 Files selected for processing (4)
  • 04-form/README.md
  • 05-effects/README.md
  • README.md
  • src/App.jsx
💤 Files with no reviewable changes (1)
  • 04-form/README.md

Comment thread README.md
Comment on lines 141 to 151
| 구분 | 과거 코드 | 현재 코드 |
|------|---------|---------|
| 방식 | Uncontrolled (`FormData`) | Controlled (`useState`) |
| 값 접근 | 제출 시 DOM에서 읽음 | state로 실시간 관리 |
| 코드량 | 적음 | 많음 |
| fetchRestaurants 선언 | `useCallback`으로 감쌈 | 일반 async 함수 |
| 의존성 배열 | `[fetchRestaurants]` | `[]` |

과거 코드는 state 없이 폼 제출 시 `FormData`로 DOM에서 한 번에 읽었다. 각 input에 `name` 속성이 있으면 키-값 쌍으로 꺼낼 수 있어 코드가 간결하다.
과거 코드는 `fetchRestaurants`를 의존성 배열에 넣기 위해 `useCallback`으로 참조를 안정화했다. 현재 코드는 `useCallback` 없이 `[]`로 뒀다.

```jsx
// 과거 — Uncontrolled
const fd = new FormData(e.currentTarget);
onAdd({ category: fd.get("category"), name: fd.get("name") });
**2. id 생성 방식**

// 현재 — Controlled
const [name, setName] = useState("");
<input value={name} onChange={(e) => setName(e.target.value)} />
```
과거 코드는 처음에 `` `a${Date.now()}` ``로 클라이언트에서 id를 생성해 POST 요청에 포함했다. 리뷰를 통해 클라이언트 생성 id의 문제(밀리초 충돌, 시스템 시간 불일치)를 인지하고 id를 보내지 않아 서버가 발급하도록 수정했다. 현재 코드도 같은 방식이다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

현재 코드와 비교 표가 뒤집혀 있습니다.

useCallback/의존성 배열 설명과 id 생성 방식 설명이 현재 src/App.jsx 구현과 맞지 않습니다. 지금 문서는 "과거 코드"와 "현재 코드"를 서로 바꿔 적은 상태라 학습자가 실제 흐름을 잘못 이해할 수 있습니다. 표와 아래 설명을 현재 구현 기준으로 다시 맞춰 주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 141 - 151, The comparison table in README.md (lines
141-151) has the "과거 코드" (past code) and "현재 코드" (current code) columns
reversed, causing the descriptions of useCallback/dependency array and id
generation to contradict the actual current src/App.jsx implementation. Swap the
column contents or re-label the columns so that "현재 코드" accurately describes
what is actually implemented in the current App.jsx code (general async function
without useCallback and empty dependency array for fetchRestaurants, and
server-side id generation). Also correct the same backwards description in the
id generation section that follows to ensure learners understand the actual
evolution and current state of the code.

Comment thread src/App.jsx Outdated
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