fix: LogoutNotice 토스트 중복 표시 방지
개발 모드 Strict Mode(App Router 기본값)의 effect mount→cleanup→remount 2회 호출로 쿼리 파라미터 감지 토스트가 두 번 뜨는 것을 실제 브라우저 검증 중 확인했다. cleanup 없는 effect라 가드가 없으면 매 remount마다 showToast가 재실행된다. hasNotifiedRef로 최초 1회만 실행되도록 고정한다 — 사용자에게 보이는 알림은 Strict Mode 유무와 무관하게 항상 1회여야 한다. Co-Authored-By: Claude Opus 5
@3861060af26628a1374b141d93654f76ed3de2b6
--- app/(public)/login/_components/logout-notice.tsx
+++ app/(public)/login/_components/logout-notice.tsx
... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 |
'use client'; |
| 2 | 2 |
|
| 3 |
-import { useEffect } from 'react';
|
|
| 3 |
+import { useEffect, useRef } from 'react';
|
|
| 4 | 4 |
import { useRouter } from 'next/navigation';
|
| 5 | 5 |
import { useFeedback } from '@/app/_hooks/use-feedback';
|
| 6 | 6 |
|
... | ... | @@ -23,15 +23,24 @@ |
| 23 | 23 |
* |
| 24 | 24 |
* 표시 후에는 쿼리 파라미터를 제거한다(router.replace) — 새로고침·북마크 재방문 시 지난 실패가 |
| 25 | 25 |
* 다시 뜨는 것을 막는다. |
| 26 |
+ * |
|
| 27 |
+ * `hasNotifiedRef`로 실행을 1회로 못박는다 — App Router는 기본 Strict Mode(next.config.ts에 |
|
| 28 |
+ * 별도 설정이 없으면 true, Next.js 13.5.1부터 기본값)라 개발 모드에서 effect가 mount→cleanup→ |
|
| 29 |
+ * remount로 2회 호출된다. 이 effect엔 cleanup이 없어 가드가 없으면 토스트가 두 번 뜬다 — |
|
| 30 |
+ * router.replace가 아직 반영되기 전(같은 커밋 내)에 두 번째 호출이 일어나 showError prop이 |
|
| 31 |
+ * 그대로 true이기 때문이다. 프로덕션은 원래 1회지만, 사용자에게 실제로 보이는 부수효과(알림)는 |
|
| 32 |
+ * Strict Mode 유무와 무관하게 항상 1회여야 한다. |
|
| 26 | 33 |
*/ |
| 27 | 34 |
export function LogoutNotice({ showError }: LogoutNoticeProps) {
|
| 28 | 35 |
const router = useRouter(); |
| 29 | 36 |
const { showToast } = useFeedback();
|
| 37 |
+ const hasNotifiedRef = useRef(false); |
|
| 30 | 38 |
|
| 31 | 39 |
useEffect(() => {
|
| 32 |
- if (!showError) {
|
|
| 40 |
+ if (!showError || hasNotifiedRef.current) {
|
|
| 33 | 41 |
return; |
| 34 | 42 |
} |
| 43 |
+ hasNotifiedRef.current = true; |
|
| 35 | 44 |
|
| 36 | 45 |
// 내부 정보(백엔드 message 원문 등)는 노출하지 않는다 — 항상 이 고정 문구만 보여준다. |
| 37 | 46 |
showToast({ variant: 'warning', message: LOGOUT_ERROR_MESSAGE });
|
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?