[올해도 아좌좌] 로그인 여부를 SSR로 잘 처리하기 (+ hydration-error)

ahyes·2023년 12월 17일
0

올해도 아좌좌

목록 보기
3/4

현재 올해도 아좌좌 서비스의 디자인을 한번 갈아 엎고 다시 만들고 있습니다.
지난 11월과 달리 모바일로 사용하는 유저가 더 많을 것이라 생각되어 모바일 중점으로 변경했습니다!

그래서 새로 네비게이션바를 만들게 되었는데 로그인 여부만 판단해서 변경해주면 간단하게 해결될거라 생각했는데 이게 생각보다 골치가 아프네요.😂

목적

로그인 여부에 따라 로그인이 되어있다면 마이페이지를, 되어있지 않다면 로그인하기를 네비게이션바에 보이게 하고싶었습니다.

발생한 에러

저에게 발생했던 에러는 다음과 같습니다.

  1. 로그인 한 뒤 로그인하기 -> 마이페이지로 변하지 않는 문제가 있었고 f5를 눌러 직접 새로고침해야만 변경되는 문제가 있었습니다.
  2. hydration에러

hydration에러는 next.js를 사용하며 가장 많이 맞닥뜨리고있는 에러인데 이 에러는 일단 왜 발생하는지 먼저 알아보겠습니다.

hydration-error 발생 이유

next.js는 SSR로 처음에 서버에서 렌더링을 한 뒤 클라이언트에서 보여주게 됩니다. (따로 ssr 옵션을 끄지 않는 한 기본적으로 모든 페이지를 사전 렌더링 함)
이때 server에서 미리 렌더링된 React 트리와 브라우저에서 첫 번째로 렌더링된 React 트리 간에 차이가 있어서 발생하는 에러입니다.

일반적인 해결방법은 여기에 있습니다.

내 코드의 문제

저같은 경우는 쿠키의 값을 받아오는데 특정 부분에서 쿠키를 받아오지 못하는 문제가 있었습니다.


현재 폴더 구조입니다.

  • 최상위 layout.tsx : 서버 컴포넌트
  • 네비게이션바 : 로그인 여부에따라 변경되어야 하기 때문에 useState 사용이 필요하다 판단되어 Navigation 클라이언트 컴포넌트로 분리

만약 로그인을 하게 된다면 login -> oauth -> home으로 이동하는 구조입니다.
oauth -> home으로 이동할 때 쿠키값이 업데이트 되는데 layout.tsx에선 쿠키 값을 제대로 받아오고 Navigation 컴포넌트에선 쿠키 값을 못받아오는 문제가 있었습니다.
Navigation 컴포넌트에선 useEffect를 사용해서 마운트 된 뒤에야 쿠키값을 제대로 받아올 수 있었고 위의 문제를 통해 원인을 생각해 본 결과

  1. 네비게이션바를 최상위 layout.tsx파일에 위치시켰고 이에 따라 렌더링되는 순서에 차이가 있어 문제가 생겼다.
  2. 쿠키 값을 제대로 못받아오는데 서버 컴포넌트와 클라이언트 컴포넌트의 차이인것 같다.

이 두 문제 때문에 발생한 오류라 생각했습니다.

해결

1번 로그인 한 뒤 로그인하기 -> 마이페이지로 변하지 않는 문제

로그인 했을 때 최상위 layout이 먼저 렌더링 되는 문제 때문에 발생한 문제라 setTimeout을 설정해 해결했습니다.

if (!getCookie('key')) {
    setTimeout(() => {
      setIsLogin(getCookie('key'));
    }, 1000);
  }

Navigation이 렌더링될 때 'key'를 키값으로 하는 쿠키가 없다면 1초 뒤 'key'를 키값으로 하는 쿠키를 저장하는 방식으로 로그인한 뒤 로그인하기로 렌더링 되도록 할 수 있었습니다.

2번 hydration-error

서버에서는 쿠키가 존재하고 클라이언트에서는 쿠키가 존재하지 않기 때문에 SSR로 서버에서 만든 React 트리는 로그인이 되어있지 않은 상태이고 이후 클라이언트에서 만든 React 트리는 로그인이 되어있는 상태로 서로 차이가 있기 때문에 문제가 발생하게 되었습니다.
기존에 로그인 초기값을 쿠키에서 직접 가져와 저장하는 방식을 사용했는데,
최상위 layout는 쿠키 값을 제대로 받아올 수 있기 때문에 최상위 layout에서 정상적인 쿠키 값을 받아와 Navigation 컴포넌트의 props로 전달하는 방식으로 문제를 해결했습니다.

profile
티스토리로 이사갑니다. https://useyhnha.tistory.com/

0개의 댓글

관련 채용 정보