useEffect에서 alert가 2번 호출된 이유
팀 프로젝트가 끝난지 바로 엊그제 같은데(근데 진짜 엊그젠데요?) 개인 프로젝트가 시작되었습니다~~~

어김 없이 나온 트러블 슈팅...?이라 해야 하나. 암튼 자료를 먼저 보시죠
🛑 alert가 2번 호출되는 현상

alert가 2번 뜨고 그 다음에 로그인 페이지로 리다이렉트 되는 것을 보실 수 있습니다.
그럼 당연히 코드에 문제가 있지 않느냐????
const ProtectedRoute = () => {
const { accessToken } = useAuthStore((state) => state);
const [redirect, setRedirect] = useState(false);
useEffect(() => {
if (!accessToken) {
alert("로그인이 필요합니다.");
setRedirect(true);
}
}, [accessToken]);
if (redirect) return <Navigate to="/login" />;
return <Outlet />;
};
위 코드를 보면 accessToken이 없을 경우 redirect 상태를 true로 변경하기 때문에,
분명 alert이 한 번 호출된 후 로그인 페이지로 이동해야 합니다.
그렇다면 왜 alert이 두 번 호출되는 것일까요?
개발 중 이중 렌더링으로 발견한 버그 수정
React는 작성하는 모든 컴포넌트가 순수 함수라고 가정합니다. 이것은 React 컴포넌트는 항상 동일한 입력(Props, State, Context)에 대해 동일한 JSX를 반환해야 한다는 것을 의미합니다.
이 규칙을 위반하는 컴포넌트는 예기치 않게 동작하며 버그를 일으킵니다. Strict Mode는 실수로 작성된 순수하지 않은 코드를 찾아내기 위해 몇 가지 함수(순수 함수여야 하는 것만)를 개발 환경에서 두 번 호출합니다.
<StrictMode> – React
The library for web and native user interfaces
ko.react.dev
✅ StrictMode를 비활성화
StrictMode는 개발 중 부작용 감지를 위해 필요한 기능이므로 비활성화하는 것은 추천되지 않습니다.
운영 환경에서는 어차피 한 번만 실행되므로, 개발 환경에서만 발생하는 문제를 피하기 위해 다른 해결책을 고려해야 합니다.
✅ useRef를 활용하여 alert 중복 호출 방지
import { Navigate, Outlet } from "react-router-dom";
import useAuthStore from "../zustand/authStore";
import { useEffect, useRef, useState } from "react";
const ProtectedRoute = () => {
const { accessToken } = useAuthStore((state) => state);
const [redirect, setRedirect] = useState(false);
const hasAlertShown = useRef(false);
useEffect(() => {
if (!accessToken && !hasAlertShown.current) {
hasAlertShown.current = true;
alert("로그인이 필요합니다.");
setRedirect(true);
}
}, [accessToken]);
if (redirect) return <Navigate to="/login" />;
return <Outlet />;
};
export default ProtectedRoute;
useRef는 값이 유지되지만 상태 변경을 유발하지 않아 두번째로 호출되더라도 hasAlertShown의 값이 true이기 때문에 alert가 호출되지 않습니다.
✅ 결론: useEffect가 두 번 실행되는 것은 정상적인 동작입니다.
React의 StrictMode는 개발 환경에서 부작용을 감지하기 위해 일부 함수들을 의도적으로 두 번 실행합니다.
이로 인해 useEffect 내부의 코드가 두 번 실행되면서 alert이 두 번 호출되는 것이며, 이는 버그가 아니라 정상적인 동작입니다.
운영 환경에서는 useEffect가 한 번만 실행되므로 실제 배포 시에는 문제가 되지 않습니다.
하지만 개발 환경에서도 alert이 두 번 호출되지 않도록 하고 싶다면, useRef를 활용하여 중복 실행을 방지하는 것이 가능합니다.