Next / does not match server-rendered HTML 에러 해결하기

최민경·2024년 7월 17일
2
post-thumbnail

Hydration error

Hydration이란?

Hydration은 서버 사이드 렌더링을 통해 사전 렌더링된 HTML 콘텐츠들을 클라이언트 측의 JavaScript와 연결하는 과정이다.

에러 설명

미션을 진행하다가 다 잘 되는데 모바일 크기에서 새로고침을 하면 에러가 났다.
코드를 수정하던 중이라 그게 문제인 줄 알고 수정을 다 롤백했는데도 에러가 나서 찾아보니 Hydration 관련 에러였다.

Error: Hydration failed because the initial 
UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching <img> in <button>.
See more info here: https://nextjs.org/docs/messages/react-hydration-error

에러 내용을 번역해보면 초기 UI가 서버에서 렌더링된 UI와 일치하지 않아서 인 거 같다.

데스크톱 UI

모바일 UI

서버에서 렌더링된 UI는 데스크톱 UI처럼 글자가 들어간 드롭다운인데
모바일 크기일 때는 이미지만 들어가서 이 부분이 일치하지 않아서라고 생각했다.

해결

해결은 의외로 쉬웠는데, 에러 메시지의 사이트를 보면 에러에 대한 정보와 해결방법을 확인할 수 있었다.

https://nextjs.org/docs/messages/react-hydration-error#why-this-error-occurred

원인

이 에러는 서버에서 사전 렌더링된 React 트리와 브라우저에서 Hydration 과정을 거치면서 렌더링된 HTML 트리 사이에 차이가 있어서 발생한 것이다.

Hydration 에러가 일어날 수 있는 다양한 원인들

  1. HTML 태그들의 잘못된 중첩
    • <p> 태그 안에 다른 <p> 태그 중첩
    • <p> 태그 안에 다른 <div> 태그 중첩
    • <p> 태그 안에 <ul> 또는 <ol> 태그 중첩
    • interactive한 태그 안에 중첩
      • <a> 태그 안에 또 다른 <a> 태그를 넣거나,
      • <button> 태그 안에 또 다른 <button> 태그를 넣는 등의 중첩
  2. 렌더링 로직에서 typeof window !== 'undefined' 같은 검사 사용
  3. 렌더링 로직에서 windowlocalStorage 같은 브라우저 전용 API 사용
  4. 렌더링 로직에서 Date() 생성자 같은 시간 의존적 API 사용
  5. HTML을 수정하는 브라우저 확장 프로그램

해결 방법

해결 방법은 mount를 판단한 상태를 하나 만들고
useEffect 훅을 사용하여 클라이언트 측에서만 실행되도록 코드를 작성하는 것이었다.

mounted라는 상태 변수로 mount되었는지 확인하고
useEffect를 통해 처음 마운트 될 경우에만 mounted 상태 변수를 true로 바꾼다.
그걸 통해서 원하는 컴포넌트를 mounted를 통한 조건부 렌더링으로 생성한다.

이 방법을 통해 서버 사이드 렌더링 중에는 이 콘텐츠가 렌더링되지 않고, 클라이언트에서 자바스크립트가 로드되고 실행된 후에만 렌더링된다. 서버 사이드 렌더링에는 렌더링 되지 않기 때문에 Hydration 에러가 발생하지 않는다.

또 다른 해결 방법 (참고용)

1. 특정 컴포넌트에 대해 SSR 비활성화
hydration 불일치를 방지하기 위해 특정 컴포넌트에 대해 SSR 비활성화를 설정하면 에러를 방지할 수 있다.

2. suppressHydrationWarning 사용
타임스탬프 같은 경우로 인해 서버와 클라이언트 간에 컨텐츠가 불가피하게 다르다면 해당 요소에 suppressHydrationWarning={true}를 추가해 Hydration 불일치 에러를 막을 수 있다.

profile
감자

1개의 댓글

comment-user-thumbnail
2024년 7월 20일

진짜 손수 겪은 문제에 대해서 잘 해결하는 것 같아서 좋당 밍경감자 최고 !

답글 달기

관련 채용 정보