[Next.js] Hydration failed because the initial UI does not match what was rendered on the server 에러

Growing_dev·2023년 4월 10일
0

Next.js

목록 보기
5/5

Portal을 만들던 중 다음과 같은 에러가 발생했습니다.

Unhandled Runtime Error
Error: Hydration failed because the initial UI does not match what was rendered on the server.

코드

Next.js가 SSR 방식을 사용하기 때문에 이 코드가 없으면 아래의 오류가 발생했고 이를 해결하고자 window의 type 검사 코드를 넣으니 Hydration error가 발생한 것이었죠.

Hydrate

Hydrate를 간략하게만 설명하자면 서버사이드에서 rendering된 정적 페이지와 번들링된 js코드를 클라이언트에게 보낸 후 js코드가 HTML DOM 위에서 다시 rendering 되면서 서로 매칭되는 과정입니다.

즉 이 코드가 들어가면서

if (typeof window === 'object') {
 return createPortal(
      children,
      document.getElementById(selector) as HTMLElement
    );
}

서버사이드에서 pre-rendering된 React 트리와 브라우저에서 처음 rendering되는 React 트리가 달랐기 때문에 발생한 에러였죠.

해결

next.js 공식 링크
문서를 참고하여 위에서 작성한 Portal 코드를 아래와 같이 수정했더니 문제가 해결되었습니다.

import { FC, ReactNode, useEffect, useState } from "react";
import { createPortal } from "react-dom";

interface PortalProps {
  children: ReactNode;
  selector: string;
}

const Portal: FC<PortalProps> = ({ children, selector }) => {
  const [element, setElement] = useState<HTMLElement | null>(null);

  useEffect(() => {
    setElement(document.getElementById(selector));
  }, [element]);

  if (element) return createPortal(children, element);

  return null;
};

export default Portal;

ssr서 document 객체에 접근하는 것을 막기 위해 if (typeof window === 'object') 코드를 삽입한 것이었는데, csr에서 실행되는 useEffect 내에서 document 객체를 참조하면 문제를 해결할 수 있었습니다.

profile
github ( https://github.com/sktjgudals ) gitlab ( https://gitlab.com/sktjgudals10 )

0개의 댓글