본문으로 바로가기

useEffect에서 alert가 2번 호출된 이유

category React.js 2025. 2. 21. 01:29

팀 프로젝트가 끝난지 바로 엊그제 같은데(근데 진짜 엊그젠데요?) 개인 프로젝트가 시작되었습니다~~~

 

어김 없이 나온 트러블 슈팅...?이라 해야 하나. 암튼 자료를 먼저 보시죠

 

🛑 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를 활용하여 중복 실행을 방지하는 것이 가능합니다.