[PWA] (34) alert 시리즈, checkingLogin 불투명

Kimmy·2025년 6월 20일

PWA_PROJECT

목록 보기
46/47

'회원가입이 완료되었습니다' 메세지 안뜸

회원가입이 되고 나면 db생성은 되는데, 메세지 출력하는 코드는 있는데, 그게 작동하지않는 문제가 있음.

 return res
        .status(201)
        .json({ message: "회원가입이 완료되었습니다.", user: newUser });

onClose(); 주석처리하기로 해결완료
이게 있어서, 가입완료 메세지가 나오기도 전에 닫혔던 것임.

 try {
      const response = await fetch("/api/signup", {
        method: "POST",
        body: formData,
      });

      const result = await response.json();

      if (response.ok) {
        setSuccessMessage("회원가입이 완료되었습니다!");
        // 필요시 로그인 상태 저장 or 리다이렉트
        // onClose();
      } else {
        setError(result.message || "회원가입에 실패했습니다.");
      }

로그인 필요 alert 메세지

로그인을 해두면, '로그인 필요'라는 에러가 안나는데, 회원가입 테스트하려고 로그아웃해둔 상태면 계속 '로그인 필요'라는 에러메세지가 뜨는문제가 있었다.

useEffect 코드를 살펴보니 if (!res.ok) throw new Error("로그인 필요"); 에서res.ok 가 아니면 에러를 throw 하고 있었다. 그리고 error 를 잡았으면, setCurrentUser(null)하는게 맞는데, 그것도 주석처리되어있는 애매한 상태였다.

  useEffect(() => {
    const fetchUser = async () => {
      try {
        const res = await fetch("/api/me", { credentials: "include" });
        if (!res.ok) throw new Error("로그인 필요");
        const user = await res.json();
        setCurrentUser(user);
      } catch (error) {
        console.error("유저 정보 불러오기 실패", error);
        // setCurrentUser(null); // 로그인 안 한 상태
      }
    };
        fetchUser();
  }, []);

위의 부족했던 코드를, 아래처럼 바꾸었다.
일단 res.ok가 의미하는것은 로그인 상태라면 /api/me가 200 OK를 반환한다는 것이다. → 즉 res.ok 가 true 이므로 에러를 throw하지 않음

반대로, (!res.ok)에 해당하는 것은 로그인하지 않은상태거나, 토큰이 없거나, 만료/손상된 경우로, /api/me가 401(또는 403 등)을 반환한다 → res.ok가 false 이므로 → 에러를 throw한다

이렇게 하면 catch 블록으로 넘어가서 에러 처리를 하게 됩니다.

정리:
res.ok는 HTTP 응답이 2xx(성공)일 때 true이다.
로그인하지 않은 상태에서 /api/me는 401(실패)이므로 res.ok가 false가 되고, 에러가 발생하는 구조였던것이다.

이는 로그인이 필요하지 않은 페이지에서는 필요없는 동작들이므로, (!res.ok)이어도, 에러를 throw 하지 않도록 하고, 그냥 setCurrentUser(null) 즉 비로그인 상태로만 처리하도록 수정했다.

        if (res.ok) {
          const user = await res.json();
          setCurrentUser(user);
        } else {
          setCurrentUser(null); // 로그인 안 한 상태로만 처리, 에러 throw X
        }
      } catch (error) {
        setCurrentUser(null);
      }
    };

로그인하지 않으면, 마이페이지가 안보여야 하는데 불투명하게 보이는 문제

useEffect(() => {
  const user = JSON.parse(localStorage.getItem("currentUser"));
  if (!user) {
    alert("로그인이 필요한 서비스입니다111.");
    router.push("/"); // 로그인 안 된 경우 홈으로 이동
    return;
  }
  setCurrentUser(user);
  setPointHistory(user.pointHistory || []);
  setCheckingLogin(false); 
}, [router]);

🎬 실행 순서

  1. localStorage에서 "currentUser" 값을 읽어온다.
  2. 값이 없으면 → 로그인 안 됐다고 판단 → 알림 띄우고 홈으로 리디렉션
  3. 값이 있으면 → 로그인 됐다고 판단 → currentUser에 저장하고
  4. 마지막으로 setCheckingLogin(false) 호출
    → 이 순간에 로그인 체크가 "끝났다"고 표시된다.

🌷 코드 설명

  1. const [checkingLogin, setCheckingLogin] = useState(true); // 로그인 상태 확인용 상태 추가
    컴포넌트가 처음 렌더링될 때 checkingLogin은 true이다.

  2. if (checkingLogin) return null;
    그래서 처음에는 이 조건에 걸려서 화면에 아무것도 안 나타난다.
    (리턴이 null이니까 React는 화면을 "비워둔다")

  3. useEffect에서 로그인 체크가 끝나면 setCheckingLogin(false)를 호출하고,
    렌더링 시 if (checkingLogin) return null; 처럼 조건문에 사용하면
    "로그인 체크가 끝나기 전까지는 아무것도 렌더링하지 않는다"는 의미가 된다.

useEffect(() => {
  const user = JSON.parse(localStorage.getItem("currentUser"));
  ...
  setCheckingLogin(false); // 로그인 확인 끝났다고 알림
}, []);

useEffect는 렌더링이 끝난 직후 실행된다. 즉, 화면은 비어있지만 그 뒤에 로그인 여부를 판단한다.

  1. 로그인 확인이 끝나면 setCheckingLogin(false)를 호출한다.

  2. 상태가 바뀌었기 때문에 컴포넌트는 다시 렌더링된다.
    그리고 이번에는 checkingLogin === false이므로 마이페이지화면이 비로소 렌더링된다.

profile
바리바리 개바리 🌼

0개의 댓글