개인과제

MBTI test(트러블 슈팅3🌟)

choijming21 2024. 9. 10. 19:55

1. 문제 발생❓

페이지 새로고침 시 로그인 상태가 유지되어 있음에도 불구하고, 로그인 페이지로 리다이렉트 되는 문제점!!

 

 

 

 

2. 원인 추론 🔎

  • 상태 초기화: 페이지 새로고침 시 React 상태('user')가 'null'로 초기화 되는 문제가 있는 것 같다.
  • 비동기 처리 타이밍: 'useEffect'에서 'fetchUserProfile' 함수가 완료되기 전에 라우팅 결정이 이루어지는 것 같다.
  • 에러 처리: 모든 에러 상황에서 자동으로 로그아웃 처리

 

제일 큰 문제는 비동기 처리 타이밍 문제인 것 같다.

페이지를 새로고침 하면 React 상태가 초기화 되어 user 상태가 null이 된다. 그리고 useEffect에서 fetchUserProfile을 비동기적으로 호출하지만, 이 함수가 완료되기 전에 라우팅 결정이 이루어진다.

 

 

즉, 다음과 같은 순서로 일어난다.

  1. 페이지 새로 고침
  2. React 상태 초기화 (user = null)
  3. 컴포넌트 마운트 및 첫 렌더링
  4. useEffect 실행 및 fetchUserProfile 함수 호출 (비동기)
  5. 라우팅 결정 (이 시점에서 user는 여전히 null)
  6. 사용자 로그인 페이지로 리다이렉트

 

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