1. 문제 발생❓
페이지 새로고침 시 로그인 상태가 유지되어 있음에도 불구하고, 로그인 페이지로 리다이렉트 되는 문제점!!
2. 원인 추론 🔎
- 상태 초기화: 페이지 새로고침 시 React 상태('user')가 'null'로 초기화 되는 문제가 있는 것 같다.
- 비동기 처리 타이밍: 'useEffect'에서 'fetchUserProfile' 함수가 완료되기 전에 라우팅 결정이 이루어지는 것 같다.
- 에러 처리: 모든 에러 상황에서 자동으로 로그아웃 처리
제일 큰 문제는 비동기 처리 타이밍 문제인 것 같다.
페이지를 새로고침 하면 React 상태가 초기화 되어 user 상태가 null이 된다. 그리고 useEffect에서 fetchUserProfile을 비동기적으로 호출하지만, 이 함수가 완료되기 전에 라우팅 결정이 이루어진다.
즉, 다음과 같은 순서로 일어난다.
- 페이지 새로 고침
- React 상태 초기화 (user = null)
- 컴포넌트 마운트 및 첫 렌더링
- useEffect 실행 및 fetchUserProfile 함수 호출 (비동기)
- 라우팅 결정 (이 시점에서 user는 여전히 null)
- 사용자 로그인 페이지로 리다이렉트
fetchUserProfile이 완료되어 user 상태를 업데이트하기 전에 이미 라우팅 결정이 끝나버리는 것이 핵심 문제이다. 이로 인해 실제로는 로그인된 상태임에도 불구하고 로그인 페이지로 리다이렉트되는 현상이 발생한다.
< 원래 코드 >
const App = () => {
const [user, setUser] = useState(null);
useEffect(() => {
const token = localStorage.getItem("authToken");
fetchUserProfile(token);
}, []);
const fetchUserProfile = async (token) => {
try {
const userProfile = await getUserProfile(token);
if (userProfile.success) {
setUser({
id: userProfile.id,
nickname: userProfile.nickname,
});
} else {
throw new Error("Failed to fetch user profile");
}
} catch (error) {
console.error(error);
alert("세션이 만료되었습니다. 다시 로그인 해주세요.");
handleLogout(false);
}
};
// ... 기타 코드 ...
};
3. 해결 과정 📋
- loading 상태 추가
- 사용자 정보 로드 완료 후 라우팅 결정
- 에러 처리 로직 개선
< 수정된 코드 >
const App = () => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const token = localStorage.getItem("authToken");
if (token) {
fetchUserProfile(token);
} else {
setLoading(false);
}
}, []);
const fetchUserProfile = async (token) => {
try {
const userProfile = await getUserProfile(token);
if (userProfile.success) {
setUser({
id: userProfile.id,
nickname: userProfile.nickname,
});
}
} catch (error) {
console.error(error);
alert("프로필 정보를 가져오는데 실패했습니다. 다시 시도해주세요.");
} finally {
setLoading(false);
}
};
if (loading) {
return <div>Loading...</div>;
}
// ... 기타 코드 ...
};
주요 변경 사항 설명
- 'loading' 상태 추가: 사용자 정보 로딩 상태를 관리한다.
- 'useEffect' 수정: 토큰이 있을 때만 'fetchUserProfile' 함수를 호출한다.
- 'fetchUserProfile' 함수 개선
- 에러 발생 시 자동 로그아웃 대신 사용자에세 알림만 표시한다.
- 함수 종료 시 항상 'setLoading(false)'를 호출하여 로딩 상태를 해제한다.
- 조건부 렌더링 추가: 로딩중일 때는 "Loading..." 메세지를 표시한다.
loading 상태를 추가함으로써 해결되는 과정 설명
- 컴포넌트가 처음 렌더링될 때, loading 상태는 true이다.
- React는 컴포넌트를 위에서 아래로 평가합니다. 따라서 if (loading) 조건을 먼저 체크한다.
- loading이 true이면, 즉시 <div>Loading...</div>을 반환하고 나머지 코드는 실행되지 않는다.
- loading이 false가 되면 (비동기 작업 완료 후), 컴포넌트가 다시 렌더링된다.
- 이때 if (loading) 조건을 통과하여 실제 라우팅 설정이 포함된 JSX가 렌더링된다.
4. 결과 ❤🔥
이러한 변경으로 사용자 정보를 완절히 로드한 후에 라우팅 결정이 이루어지므로, 새로고침 시에도 로그인 상태가 올바르게 유지될 수 있었다!
'개인과제' 카테고리의 다른 글
리그오브레전드 정보앱(트러블 슈팅1🌟) (0) | 2024.10.01 |
---|---|
MBTI 과제 마무리 (0) | 2024.09.11 |
MBTI test(트러블 슈팅2🌟) (0) | 2024.09.10 |
MBTI test(트러블 슈팅1🌟) (0) | 2024.09.10 |
로그인 기능 구현하기 (0) | 2024.08.27 |