FrontEnd Develop/Project : Team Nova MJ Search

LocalStorage와 SessionStorage를 활용한 로그인 전역 상태 유지 및 Fetching UI JANK, UX 개선

Frisbeen 2025. 3. 6. 19:09

 

웹 애플리케이션에서 로그인 상태를 유지하는 것은 중요한 UX 요소 중 하나라고 생각합니다.

 

특히 새로고침 시에도 로그인 상태를 유지하려면 LocalStorage SessionStorage를 적절히 활용해야 합니다. 또한, 사용자 경험을 개선하기 위해 로딩 컴포넌트를 활용하는 것도 효과적입니다.

 

 

이번 포스트에서는 제가 프로젝트를 진행하며 로그인 상태를 저장하고, 새로고침 시에도 유지되도록 설정하는 방법 로딩 컴포넌트를 추가하여 UI를 더욱 부드럽게 효율적으로 만드는 방식을 포스팅하겠습니다.


로그인 상태를 저장하는 방법

React에서 로그인 상태를 유지하기 위해 LocalStorage와 SessionStorage를 조합하여 사용할 수 있습니다.

  • LocalStorage: UUID(사용자 식별자)와 같은 장기 저장 데이터를 저장 (로그아웃 전까지 유지됨)
  • SessionStorage: AccessToken(인증 토큰)과 같은 보안이 중요한 데이터를 저장 (브라우저 탭이 닫히면 삭제됨)

LocalStorage와 SessionStorage에 로그인 정보 저장

const login = async (userInfo) => {
  try {
    const data = await loginApi(userInfo);
    setAccessToken(data.accessToken);
    setIsLoggedIn(true);
    
    sessionStorage.setItem('accessToken', data.accessToken); // 인증 토큰 저장
    localStorage.setItem('uuid', data.uuid); // 사용자 UUID 저장
  } catch (error) {
    console.error('❌ 로그인 실패:', error);
  }
};

새로고침 시 저장된 데이터 불러오기

useEffect(() => {
  const storedToken = sessionStorage.getItem('accessToken');
  const storedUuid = localStorage.getItem('uuid');

  if (storedToken) {
    setAccessToken(storedToken);
    setIsLoggedIn(true);
  }

  if (storedUuid) {
    setUuid(storedUuid);
  }
}, []);

위 코드에서는 useEffect를 활용하여 앱이 처음 렌더링될 때 저장된 로그인 정보를 불러오도록 설정했습니다.

그저 초기렌더링 시에만 데이터를 가져오는게 좀 더 적절하다고 판단하여, 의존성은 이 부분에선 굳이 추가할 부분이 없다 판단하여 비웠습니다.

 


프로필 데이터를 가져오는 API 요청

로그인 상태가 유지되면 프로필 정보를 API에서 가져와 화면에 표시해야 합니다.

useEffect(() => {
  const fetchUserData = async () => {
    if (isLoggedIn && uuid) {
      try {
        const response = await apiClient.get(`/members/${uuid}`);
        setUser(response.data.data);
      } catch (error) {
        console.error('서버 통신 오류:', error);
      } finally {
        setLoading(false);
      }
    } else {
      setLoading(false);
    }
  };
  fetchUserData();
}, [isLoggedIn, uuid, setUser]);

로그인 후 자동으로 사용자 프로필 정보를 불러올 수 있게 하였습니다.

 

이 부분에서 UI Jank가 발생하는데, 

서버에서 데이터를  가져올때 한 0.05초 정도 동안 fetching 되기 전 값 ( Null 값이 프로필에 표시가 되었습니다)

 

그렇게까지 크게 UX를 떨어트리는 부분은 아니지만, 자신의 로그인 상태를 확인하기 위해서 메인페이지의 프로필 섹션을 사용자가 많이 본다는 가정하에 UX 개선포인트가 존재한다 생각하여 로딩 컴포넌트를 추가해야겠다고 판단하였습니다.

 


UX 개선: 로딩 컴포넌트 추가

로딩 컴포넌트 추가 ( LoadingComponent Importing)

props는 message 하나만 설정하였습니다. 로딩스타일은 스피너를 활용하였고 메인페이지와 잘 어울리게끔 스타일링 하였습니다.

if (loading) {
  return <LoadingComponent message="프로필 정보를 불러오는 중..." />;
}

프로필 박스 내부에서 로딩 상태를 표시

여기서도 상당한 고민이 있었는데, 삼항연산자를 활용하여 프로필 컴포넌트 내부에 로딩 컴포넌트를 띄울까

아니면 아예 밖에 loading 상태를 조건문으로 하여 애초에 프로필 컴포넌트 자체가 로딩이 끝나기 전에는 보이지 않게 할까

 

코드보면 전자겠습니다.

return (
  <div css={profileContainerStyle}>
    {loading ? (
      <div css={loadingContainerStyle}>
        <LoadingComponent message="프로필을 불러오는 중..." />
      </div>
    ) : (
      <ProfileContent />
    )}
  </div>
);

이렇게 하면 로딩 중일 때도 레이아웃이 유지되며, UI가 깔끔하게 렌더링됩니다.


 지금까지의 긍정적 결과

 LocalStorage와 SessionStorage를 조합하여 로그인 상태를 유지

  새로고침 시 저장된 데이터를 불러와 로그인 유지

  API를 통해 사용자 정보를 가져와 화면에 표시

  UX 개선을 위해 로딩 컴포넌트를 추가하여 자연스러운 렌더링 구현