SSR 하이드레이션 오류

hyemeeny·2025년 2월 14일

Next

목록 보기
7/9
post-thumbnail

📌 SSR 하이드레이션 오류

Error: Text content does not match server-rendered HTML.
See more info here: https://nextjs.org/docs/messages/react-hydration-error

📖 문제

애플리케이션을 렌더링하는 동안, 서버 사이드 렌더링(SSR/SSG)된 React 트리와 브라우저에서 첫 렌더링 시 렌더링된 React 트리 간에 차이가 있다.

이 오류는 서버 사이드 렌더링(SSR) 중에 발생하는 하이드레이션(hydration) 오류로, 서버에서 렌더링된 HTML과 클라이언트에서 렌더링된 HTML이 일치하지 않아서 발생한다.

  • 주로 날짜와 시간과 같은 동적인 데이터를 서버와 클라이언트에서 동시에 렌더링하려고 할 때 발생

formatRelativeTime 함수는 현재 시간과 입력된 시간의 차이를 계산하여 상대 시간을 표시하는 함수인데, 클라이언트에서 렌더링할 때 시간이 조금씩 다르게 계산된 것이 오류의 원인으로 생각된다. 서버에서 렌더링될 때와 클라이언트에서 렌더링될 때 Date.now()가 다를 수 있기 때문에, 클라이언트에서만 동적으로 계산되도록 수정해야 한다.

📖 해결

  • 초기 렌더링 시 서버와 클라이언트 값 일치: 클라이언트에서만 동적으로 계산되도록 useEffect를 사용하여 클라이언트에서만 시간을 계산하고 업데이트하도록 처리
  • formatRelativeTime을 클라이언트에서만 계산: 컴포넌트가 마운트된 후에 시간을 계산하도록 하여 서버와 클라이언트의 값 차이를 없애야 한다.
export const RelativeTimeComponent = ({ timestamp }: { timestamp: string }) => {
  const [relativeTime, setRelativeTime] = useState<string>("");

  useEffect(() => {
    // 클라이언트에서만 시간 계산
    const relative = formatRelativeTime(timestamp);
    setRelativeTime(relative);
  }, [timestamp]);

  return <span>{relativeTime}</span>; 
};

...

// 다른 컴포넌트에서 불러올 때
<p>{RelativeTimeComponent({ timestamp: link.createdAt })}</p>

다른 예시

div가 p 태그 내부에 있으면 잘못된 HTML이므로 hydration 불일치가 발생할 수 있다.

export const IncorrectComponent = () => {
  return (
    <p>
      <div>
        This is not correct and should never be done because the p tag has been
        abused
      </div>
      <Image src="/vercel.svg" alt="" width="30" height="30" />
    </p>
  )
}

0개의 댓글