회원가입이 되고 나면 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 || "회원가입에 실패했습니다.");
}

로그인을 해두면, '로그인 필요'라는 에러가 안나는데, 회원가입 테스트하려고 로그아웃해둔 상태면 계속 '로그인 필요'라는 에러메세지가 뜨는문제가 있었다.
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]);
const [checkingLogin, setCheckingLogin] = useState(true); // 로그인 상태 확인용 상태 추가
컴포넌트가 처음 렌더링될 때 checkingLogin은 true이다.
if (checkingLogin) return null;
그래서 처음에는 이 조건에 걸려서 화면에 아무것도 안 나타난다.
(리턴이 null이니까 React는 화면을 "비워둔다")
useEffect에서 로그인 체크가 끝나면 setCheckingLogin(false)를 호출하고,
렌더링 시 if (checkingLogin) return null; 처럼 조건문에 사용하면
"로그인 체크가 끝나기 전까지는 아무것도 렌더링하지 않는다"는 의미가 된다.
useEffect(() => {
const user = JSON.parse(localStorage.getItem("currentUser"));
...
setCheckingLogin(false); // 로그인 확인 끝났다고 알림
}, []);
useEffect는 렌더링이 끝난 직후 실행된다. 즉, 화면은 비어있지만 그 뒤에 로그인 여부를 판단한다.
로그인 확인이 끝나면 setCheckingLogin(false)를 호출한다.
상태가 바뀌었기 때문에 컴포넌트는 다시 렌더링된다.
그리고 이번에는 checkingLogin === false이므로 마이페이지화면이 비로소 렌더링된다.