본문 바로가기
React TIL

[React] Day_69 팀 프로젝트 작업 관련 트러블슈팅 (1)

by 림졍 2024. 12. 26.
728x90
반응형

모의면접 보기전, 파르르 떨고있는 me.gif

 

모의면접보고...

디자인 수정하고...

PR 열심히 훑어보고...

챌린지 테스트 보오고...

오류난거 어떻게 할지 찾아보니.. 시간 다 가버렸죠?

빠아르게 뜨라블슈띵 진행해보도록 할게요?

레츠고.

 

Layout - 말도 많고 탈도 많았던 hydration error 해결기

 

와... 와이라노!!

 

 

문제 상황

 

src/app에 위치한 전역으로 뿌려주는 layout.tsx에

SideNav와 HeadNav라는 컴포넌트를 넣어 페이지를 구성하던 중...

해당 컴포넌트가 필요없는 auth 관련 페이지에서 렌더링되는 이슈가 발생했다..

 

 

그래서 auth 폴더 내부에 layout 따로, 컴포넌트가 들어갈 layout인 (dashboard)라는 폴더를 생성하여

내부에 layout.tsx를 생성하여 렌더링을 하게끔 구조를 수정한 림졍,

 

그러나 큰 문제는 따로 있었으니...

 

아니 이게 뭔가 넥스트 양반!!

 

근데.. 하필 해당 컴포넌트들이 클라이언트 컴포넌트라 hydration 에러가 떠버렸다...!

따라서, 림졍은... 해당 컴포넌트들을 서버컴포넌트들로 바꿔주는 대대적인 공사를 진행하게 되는데..

그렇다. 냅다 만들어놓고 생고생을 했다!!

 

하지만 그럼에도... 우리의 next..양반은..

 

아오 왜그러는데!!!

 

또 똑같이 오류를 뱉고 있고... ^^;;

그렇게 왜 그런지 이유를 모르고 크리스마스를 통째로 날리게 되는데.. ㅠㅡㅠ)p

 

 

문제 원인 분석

 

크게 문제를 해결하는 과정을 나열해보자면 아래와 같았다.

 

레이아웃 구조

  • src/app/layout.tsx 파일에서 SideNav와 HeadNav 컴포넌트를 전역적으로 렌더링함
  • But, auth 와 같이 해당 컴포넌트가 필요 없는 페이지에서도 불필요하게 렌더링됨

구조 수정

  • 위의 문제를 해결하기 위해, auth 페이지와 다른 레이아웃을 사용하도록
  • dashboard 폴더에 별도의 layout.tsx를 생성 → SideNav와 HeadNav 포함하는 레이아웃을 별도로 분리

Hydration Error 발생

  • 분리한 dashboard/layout.tsx의 SideNav와 HeadNav 컴포넌트들이 클라이언트 컴포넌트로 설정되어 있어
  • SSR 시 서버와 클라이언트의 HTML이 일치하지 않아 Hydration Error가 발생!

 

 

문제 해결 과정

 

해결은 아래 과정처럼 순차적으로 진행되었다.

 

클라이언트 컴포넌트 → 서버 컴포넌트 변환

  • SideNav와 HeadNav를 서버 컴포넌트로 변환하여 SSR 환경에서 해결 시도

에러 지속 발생

  • 서버 컴포넌트로 변환했음에도 불구하고 Hydration Error가 계속 발생함

중복 HTML 렌더링 문제 발견

  • 문제의 원인은 src/app/layout.tsx에서 이미 <html>, <body> 태그를 렌더링하고 있었는데,
    dashboard/layout.tsx에서도 동일하게 <html>과 <body>를 중복으로 렌더링하고 있었다..!

→ 이로 인해 서버와 클라이언트에서 서로 다른 HTML 구조가 생성되었고, Hydration Error로 이어지게 됨..

 

해결 방법

 

 

  • dashboard/layout.tsx에서 <html>, <body> 태그를 제거하여 중복 렌더링 문제 해결!

 

결과적으로 div로 감싸는 형태로 수정하여 문제 해결 완~ 뜨라블슈띵 끝! ^-^)b

 

 

코드 수정 전/후

 

- 수정 전 (Hydration Error 발생 코드)

// dashboard/layout.tsx
return (
  <html lang="en">
    <body>
      <HeadNav user={serverState.user} />
      <SideNav />
      <main className="flex-1">{children}</main>
    </body>
  </html>
);

 

- 수정 후 (Hydration Error 해결 코드)

// dashboard/layout.tsx
return (
  <>
    <HeadNav user={serverState.user} />
    <SideNav />
    <main className="flex-1">{children}</main>
  </>
);

 

 

결과

  • Hydration Error가 사라지고, SSR과 클라이언트 컴포넌트의 렌더링이 정상적으로 동작!
  • 레이아웃 구조를 명확히 분리 → 대시보드와 인증 페이지에서 각각 다른 레이아웃을 사용

 

 

교훈

  • Next.js에서 레이아웃을 나눌 때 전역 layout.tsx는 <html>, <body>를 포함하므로, 하위 레이아웃에는 <html>, <body> 넣지 말긔
  • Hydration Error, 클라이언트와 서버의 HTML 불일치에서 발생! → HTML 구조가 일치하는지 주기적으로 확인하는 습관 들이기

 

728x90
반응형

'React TIL' 카테고리의 다른 글

[React] Day_71 데일리 정리  (0) 2024.12.30
[React] Day_70 오늘의 정리  (0) 2024.12.27
[React] Day_68 데일리 정리  (1) 2024.12.24
[React] Day_67 데일리 정리  (0) 2024.12.23
[React] Day_65 데일리 정리  (1) 2024.12.19