Next.js

Next.js 하이드레이션 (Hydration)

해보구 2025. 3. 12. 11:34
반응형

Next.js 하이드레이션 (Hydration) 정리

Next.js에서 하이드레이션(Hydration)이란 서버에서 렌더링된 HTML을 클라이언트에서 React 컴포넌트로 변환하는 과정이다. 즉, 서버에서 생성된 정적인 HTML이 클라이언트에서 React의 상태와 이벤트를 갖춘 동적인 페이지로 변환되는 과정을 의미한다.


 

하이드레이션이 필요한 이유

  1. SSR/SSG 이후 React 기능 활성화
    • Next.js는 SSR(Server-Side Rendering)이나 SSG(Static Site Generation)으로 HTML을 미리 생성한다.
    • 하지만 서버에서 내려준 HTML에는 React의 이벤트 핸들러나 상태가 포함되지 않음.
    • 클라이언트에서 하이드레이션을 통해 React가 takeover(인수)하면서 이벤트 및 상태를 연결한다.
  2. SEO & 성능 최적화
    • SSR/SSG를 활용하면 SEO에 유리하고, 페이지 로딩 속도가 빨라진다.
    • 하이드레이션이 완료되면 클라이언트에서 불필요한 리렌더링을 줄이는 것이 핵심.

 

하이드레이션 에러 (Hydration Mismatch)

Next.js에서 자주 발생하는 에러 중 하나가 "Hydration failed because the initial UI does not match what was rendered on the server" 같은 하이드레이션 실패 오류다.

 

원인

  1. 서버에서 렌더링된 HTML과 클라이언트에서 렌더링되는 HTML이 다름
    • 예를 들어, Date.now()Math.random() 같은 값은 서버와 클라이언트에서 다르게 계산될 수 있음.
  2. 클라이언트 상태(State) 관리 오류
    • 서버에서 렌더링한 HTML이 클라이언트에서 상태 업데이트 후 다르게 보일 때 발생.
  3. 브라우저 전용 코드가 서버에서 실행됨
    • 예: window 객체를 직접 사용하거나, localStorage에서 값을 가져오는 코드.

 

하이드레이션 오류 해결 방법

1. 브라우저 전용 코드라면 useEffect 사용

 

  • window, localStorage 같은 브라우저 전용 API는 서버에서 실행되지 않도록 처리해야 함.
import { useEffect, useState } from "react";

export default function Page() {
  const [width, setWidth] = useState(0);

  useEffect(() => {
    setWidth(window.innerWidth);
  }, []);

  return <p>{width}</p>;
}

 

 

 

2. 동적인 데이터는 useEffect에서 설정

  • Date.now(), Math.random() 같은 값은 서버에서 계산하지 않도록 처리.
mport { useEffect, useState } from "react";

export default function Page() {
  const [time, setTime] = useState(null);

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

  return <p>{time}</p>;
}

 

 

3. SSR이 필요 없는 컴포넌트는 dynamic으로 클라이언트에서만 렌더링

  • Next.js의 next/dynamic을 사용해서 서버에서는 렌더링하지 않고, 클라이언트에서만 로드하도록 설정 가능.
import dynamic from "next/dynamic";

const ClientOnlyComponent = dynamic(() => import("../components/ClientOnlyComponent"), {
  ssr: false,
});

export default function Page() {
  return <ClientOnlyComponent />;
}

 

 

4. Key Props를 명확하게 설정

  • 리스트를 렌더링할 때 key 값이 불규칙하면 Hydration Mismatch가 발생할 수 있음.
  • map()을 사용할 때는 항상 고유한 key 값을 지정해줘야 함.
{items.map((item) => (
  <div key={item.id}>{item.name}</div> // item.id 같은 고유한 값 사용
))}

 

 

정리

  • 하이드레이션은 서버에서 생성된 HTML을 React가 takeover하는 과정이다.
  • 서버와 클라이언트의 UI가 다르면 Hydration Mismatch 오류 발생.
  • useEffect, next/dynamic, key 설정 등을 통해 오류를 방지할 수 있다.
  • 불필요한 하이드레이션을 줄이면 Next.js 성능이 더 좋아진다.

 

 

회고

면접 질문으로 하이드레이션 문제에 대해 질문을 받았다. 갑자기 생소한 단어가 들려와 모른다고 대답했는데 너무 아쉬운게 이건 내가 nextjs 15버전 하고 gsap 활용할때 발생해서 애를 많이먹다가 14버전으로 마이그레이션한 일이 나중에 떠올렸다. 다시 기록하고 제대로 숙지를 해야겠다.

반응형