Skip to content

20260102 #121 토스트 전역 핸들링을 위한 커스텀 훅 use toast 추가#125

Merged
Chuseok22 merged 6 commits intotestfrom
20260102_#121_토스트_전역_핸들링을_위한_커스텀_훅_useToast_추가
Jan 2, 2026

Hidden character warning

The head ref may contain hidden characters: "20260102_#121_\ud1a0\uc2a4\ud2b8_\uc804\uc5ed_\ud578\ub4e4\ub9c1\uc744_\uc704\ud55c_\ucee4\uc2a4\ud140_\ud6c5_useToast_\ucd94\uac00"
Merged

20260102 #121 토스트 전역 핸들링을 위한 커스텀 훅 use toast 추가#125
Chuseok22 merged 6 commits intotestfrom
20260102_#121_토스트_전역_핸들링을_위한_커스텀_훅_useToast_추가

Conversation

@Chuseok22
Copy link
Member

@Chuseok22 Chuseok22 commented Jan 2, 2026

✨ 변경 사항


✅ 테스트


  • 수동 테스트 완료
  • 테스트 코드 완료

Summary by CodeRabbit

  • 신기능

    • 중앙화된 토스트 알림 훅을 추가하고 앱 전반에 통합했습니다.
  • 리팩터링

    • 토스트 관리 로직을 중앙화하여 알림 표시가 일관되게 동작합니다.
  • 버그 수정

    • 하단 네비게이션으로 페이지 이동 시 replace 동작을 적용했습니다.
  • Chores

    • 버전을 0.4.1로 업데이트했습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

@Chuseok22 Chuseok22 requested a review from Copilot January 2, 2026 05:07
@Chuseok22 Chuseok22 self-assigned this Jan 2, 2026
@Chuseok22 Chuseok22 added the enhancement 기능 개선/향상 (Enhancement) label Jan 2, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

버전 정보(CHANGELOG, package.json, 상수)가 0.4.1로 업데이트되었고, 중앙화된 useToast 훅이 추가되어 MenuPageContainer가 로컬 토스트 상태에서 해당 훅으로 전환되었습니다.

Changes

결합(Cohort) / 파일(들) 변경 요약
버전 정보 업데이트
CHANGELOG.md, package.json, src/constants/version.ts
패키지 및 릴리스 노트 버전을 0.4.00.4.1로 일관되게 업데이트; CHANGELOG에 0.4.1 항목 추가
토스트 훅 추가
src/shared/hooks/useToast.ts
새로운 useToast(duration?: number, animationDuration?: number) 훅 추가: 메시지/가시성 상태, 충돌 안전 타이머, 자동 숨김 및 언마운트 정리 로직 제공
토스트 사용 전환
src/features/menu/components/MenuPageContainer.tsx
로컬 toastVisible/toastMessage 제거; useToastshowToast로 성공/오류 메시지 표시 로직 전환 (타임아웃 기반 가시성 로직 제거)

Sequence Diagram(s)

sequenceDiagram
    participant UI as MenuPageContainer
    participant Hook as useToast
    participant Toast as CartToast
    Note over UI,Hook: 사용자 액션: 장바구니에 추가
    UI->>Hook: showToast("장바구니에 쏙 담았어요!")
    alt 기존 토스트 표시 중
        Hook->>Hook: hide current toast (clear timers)
        Hook-->>Hook: wait animationDuration
    end
    Hook->>Hook: set message, visible = true
    Hook->>Toast: render with visible/message
    Hook->>Hook: schedule auto-hide timer (duration)
    Note over Hook,Toast: auto-hide 또는 추가 showToast로 대체 가능
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested labels

feat

Poem

🐰 토스트는 한곳에 모여,
훅으로 빙글빙글 춤추네,
메뉴에서 메시지 휙—나와,
버전은 살금 0.4.1,
토끼는 깡충깡충 기뻐해요 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 주요 변경사항인 useToast 커스텀 훅 추가와 전역 토스트 핸들링을 명확히 반영하고 있으며, 버전 업데이트와 네비게이션 수정은 부가적인 변경사항입니다.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 168673a and 815ef0d.

📒 Files selected for processing (1)
  • src/shared/hooks/useToast.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a custom useToast hook to centralize toast message handling across the application, replacing manual state management in components. The version is bumped from 0.4.0 to 0.4.1.

  • Introduces a reusable useToast hook with timer conflict prevention and toast replacement logic
  • Refactors MenuPageContainer to use the new hook, eliminating duplicate toast state management code
  • Updates application version to 0.4.1 across package files and changelog

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/shared/hooks/useToast.ts New custom hook for managing toast visibility, messages, and timer lifecycle
src/features/menu/components/MenuPageContainer.tsx Refactored to use the new useToast hook instead of manual state management
src/constants/version.ts Version bumped to 0.4.1
package.json Version bumped to 0.4.1
package-lock.json Version bumped to 0.4.1
CHANGELOG.md Added entry for version 0.4.1

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +26 to +68
const showToast = useCallback((message: string) => {
// 기존 타이머 정리
if (timerRef.current) {
clearTimeout(timerRef.current);
}
if (hideTimerRef.current) {
clearTimeout(hideTimerRef.current);
}

// 이미 토스트가 표시중이면 먼저 제거
if (visibleRef.current) {
// 기존 토스트 숨김
setVisible(false);
visibleRef.current = false;

// 애니메이션 완료 대기
hideTimerRef.current = setTimeout(() => {
setMessage(message);
setVisible(true);
visibleRef.current = true;

// duration 후 토스트 숨김
timerRef.current = setTimeout(() => {
setVisible(false);
visibleRef.current = false;
timerRef.current = null;
}, duration);

hideTimerRef.current = null;
}, animationDuration);
} else {
// 기존 토스트가 없는 경우
setMessage(message);
setVisible(true);
visibleRef.current = true;

timerRef.current = setTimeout(() => {
setVisible(false);
visibleRef.current = false;
timerRef.current = null;
}, duration);
}
}, [duration, animationDuration]);
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The showToast callback function depends on duration and animationDuration, which means it will be recreated whenever these values change. However, since duration and animationDuration are hook parameters that could change between renders, this could cause unnecessary recreations of the callback. Consider removing duration and animationDuration from the dependency array and using refs instead, or add a comment explaining why they should trigger callback recreation.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +67
if (visibleRef.current) {
// 기존 토스트 숨김
setVisible(false);
visibleRef.current = false;

// 애니메이션 완료 대기
hideTimerRef.current = setTimeout(() => {
setMessage(message);
setVisible(true);
visibleRef.current = true;

// duration 후 토스트 숨김
timerRef.current = setTimeout(() => {
setVisible(false);
visibleRef.current = false;
timerRef.current = null;
}, duration);

hideTimerRef.current = null;
}, animationDuration);
} else {
// 기존 토스트가 없는 경우
setMessage(message);
setVisible(true);
visibleRef.current = true;

timerRef.current = setTimeout(() => {
setVisible(false);
visibleRef.current = false;
timerRef.current = null;
}, duration);
}
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

There's a potential race condition between the visible state and visibleRef. When showToast is called while a toast is already visible, the code sets both setVisible(false) and visibleRef.current = false at lines 38-39, then schedules state updates in a setTimeout. If showToast is called again during the animation delay (before line 42's setTimeout executes), the visibleRef check at line 36 will be false (because it was set to false at line 39), causing the else branch to execute and potentially creating a race condition with the pending setTimeout. Consider using a more robust state machine or queueing mechanism to handle rapid consecutive calls.

Copilot uses AI. Check for mistakes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/shared/hooks/useToast.ts (1)

20-24: 이중 상태 관리 패턴 개선 고려

현재 visible 상태를 useStateuseRef 두 가지 방식으로 관리하고 있습니다. visibleRef는 동기적 확인을 위해 사용되는 것으로 보이나, 이러한 패턴은 상태 동기화 문제를 일으킬 수 있습니다.

대부분의 경우 useState만으로도 충분하며, 타이머 내부에서 최신 상태를 참조해야 한다면 함수형 업데이트 setVisible(prev => ...) 패턴을 사용하는 것이 더 안전합니다. 현재 구현이 작동하긴 하지만, 향후 유지보수성을 위해 단일 상태 관리 방식으로 리팩토링을 고려해보세요.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fa9d59 and 168673a.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • CHANGELOG.md
  • package.json
  • src/constants/version.ts
  • src/features/menu/components/MenuPageContainer.tsx
  • src/shared/hooks/useToast.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/features/menu/components/MenuPageContainer.tsx (1)
src/shared/hooks/useToast.ts (1)
  • useToast (16-83)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Agent
🔇 Additional comments (7)
src/constants/version.ts (1)

1-1: 버전 업데이트 확인

버전이 0.4.0에서 0.4.1로 정상적으로 업데이트되었습니다. package.json과 일관성이 유지되고 있습니다.

package.json (1)

3-3: 버전 업데이트 확인

package.json의 버전이 0.4.1로 정상적으로 업데이트되었습니다.

src/shared/hooks/useToast.ts (2)

26-68: 토스트 교체 로직 검증 필요

토스트 교체 로직이 복잡하게 구현되어 있습니다. 특히 showToast가 빠르게 연속으로 호출될 경우(예: 사용자가 버튼을 빠르게 여러 번 클릭) 다음과 같은 동작을 확인해주세요:

  1. 애니메이션 중간에 새로운 토스트가 요청되었을 때 예상대로 동작하는지
  2. animationDuration 대기 중에 또 다른 showToast가 호출되면 타이머가 올바르게 정리되는지

수동 테스트로 확인하시거나, 다음과 같이 연속 호출 시나리오를 테스트해보세요:

// 테스트 시나리오
showToast("첫 번째 메시지");
setTimeout(() => showToast("두 번째 메시지"), 100);
setTimeout(() => showToast("세 번째 메시지"), 150);

71-80: 클린업 로직 확인

컴포넌트 언마운트 시 타이머를 정리하는 로직이 올바르게 구현되었습니다.

src/features/menu/components/MenuPageContainer.tsx (3)

13-13: useToast 훅 임포트 확인

새로운 useToast 훅을 올바르게 임포트했습니다.


30-30: useToast 훅 사용 확인

로컬 토스트 상태 관리에서 중앙화된 useToast 훅으로 성공적으로 리팩토링되었습니다. 구조 분해 할당과 프로퍼티 이름 변경(visible: toastVisible, message: toastMessage)도 깔끔하게 처리되었습니다.


47-56: 장바구니 추가 핸들러 개선 확인

showToast를 사용하여 성공 및 에러 메시지를 표시하도록 깔끔하게 리팩토링되었습니다. 기존의 로컬 상태 관리와 수동 타이머 처리가 제거되어 코드가 더 간결해졌습니다.

@Chuseok22 Chuseok22 merged commit c3ef210 into test Jan 2, 2026
1 of 2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 2, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement 기능 개선/향상 (Enhancement)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 [기능개선][토스트] 토스트 전역 핸들링을 위한 커스텀 훅 useToast 추가

2 participants