전체 목록
ReactHard#435

React에서 hydration mismatch가 발생하는 원인과 해결 방법을 설명해주세요.

#React#Hydration#SSR#Next.js

답변 포인트

서버가 만든 HTML과 클라이언트 첫 렌더 결과가 달라지는 경우를 생각해보세요.

정답 및 해설

빠른 요약

Hydration mismatch는 서버에서 생성한 HTML과 클라이언트가 처음 렌더링한 결과가 다를 때 발생합니다. SSR 환경에서 React는 기존 HTML에 이벤트를 붙이며 hydration을 수행하는데, 이때 마크업이 다르면 경고나 UI 깨짐이 생길 수 있습니다.

Hydration mismatch는 서버에서 생성한 HTML과 클라이언트가 처음 렌더링한 결과가 다를 때 발생합니다. SSR 환경에서 React는 기존 HTML에 이벤트를 붙이며 hydration을 수행하는데, 이때 마크업이 다르면 경고나 UI 깨짐이 생길 수 있습니다.

흔한 원인은 다음과 같습니다.

  • 렌더 중 Date.now(), Math.random() 사용
  • 서버와 클라이언트의 locale/timezone 차이
  • 브라우저에서만 가능한 window, localStorage 값을 첫 렌더에 사용
  • 조건부 렌더링 결과가 서버/클라이언트에서 다름
  • 잘못된 HTML nesting

해결의 기본은 첫 렌더 결과를 서버와 클라이언트에서 동일하게 만드는 것입니다. 브라우저 전용 값은 useEffect 이후에 읽거나, 초기 placeholder를 두고 클라이언트 마운트 후 교체합니다.

TSX
function ClientTime() {
  const [time, setTime] = useState<string | null>(null);

  useEffect(() => {
    setTime(new Date().toLocaleTimeString());
  }, []);

  return <span>{time ?? '시간 불러오는 중'}</span>;
}

정말 의도적으로 다를 수밖에 없는 텍스트에는 suppressHydrationWarning을 제한적으로 사용할 수 있지만, 구조 불일치를 덮는 용도로 남용하면 안 됩니다.

관련 질문

같은 카테고리/태그 기준