코드도보통지

7관문. Hydration Mismatch

관문 7 / 7

서버/클라이언트 HTML 불일치 에러를 진단하고 올바른 방법으로 수정하라.

📖 이론 비급

Hydration Mismatch 디버깅 정공법

서버 HTML과 클라이언트 첫 렌더 결과가 다르면 리액트가 에러를 던진다.

흔한 원인:

  • typeof window 분기
  • Math.random(), Date.now() 사용
  • localStorage, sessionStorage 초기값
  • 브라우저 전용 API

정공법: suppressHydrationWarning은 최후 수단이다. const [mounted, setMounted] = useState(false)와 useEffect로 서버와 클라이언트의 첫 렌더를 일치시킨 후 마운트 이후에 다른 값을 표시하라.

⚔️ 수련 코드

'use client';
import { useState, useEffect } from 'react';

// 아래 컴포넌트들의 Hydration 에러를 수정하라

// 문제 1: Math.random()은 서버/클라이언트에서 다른 값을 생성
function RandomId() {
  const id = Math.random().toString(36).slice(2);
  return <span>ID: {id}</span>;
}

// 문제 2: window 객체는 서버에 없다
function WindowSize() {
  const width = typeof window !== 'undefined' ? window.innerWidth : 0;
  return <span>너비: {width}px</span>;
}

// 문제 3: localStorage는 서버에 없다
function SavedTheme() {
  const theme = typeof window !== 'undefined'
    ? localStorage.getItem('theme') || 'light'
    : 'light';
  return <span>테마: {theme}</span>;
}

// TODO: 각 컴포넌트를 useEffect + mounted 패턴으로 수정하라

export default function App() {
  return (
    <div>
      <RandomId />
      <WindowSize />
      <SavedTheme />
    </div>
  );
}