Next.js Hydration 에러useEffect Hydration 해결법조건부 렌더링 HydrationSSR CSR 불일치Next.js 렌더링 깜빡임

Hydration Error와 mounted 상태 관리에 대한 설명

KUKJIN LEE
KUKJIN LEE
2025년 3월 7일
279

문제 상황

// 문제가 있는 코드
export const FeatureToggles = () => {
  const { user } = useAuth();
  const isAdmin = user?.email === 'test@gmail.com';

  return (
    <div>
      {isAdmin && <Link>글쓰기</Link>} // 💥 Hydration Error 발생
    </div>
  );
};

발생 원인

쉽게 얘기하면 순서가 어긋나기 때문에 문제가 발생한다.

  • 서버 사이드 렌더링 (SSR)

  • Next.js는 첫 렌더링을 서버에서 수행

  • 이때 useAuth()의 초기 상태는 null 또는 빈 상태

  • 따라서 isAdminfalse가 되어 버튼이 렌더링되지 않음

  • 클라이언트 사이드 렌더링

  • 브라우저에서 JavaScript가 실행되면서 useAuth()가 실제 유저 정보를 가져옴

  • isAdmintrue가 되어 버튼이 나타남

  • 이 차이로 인해 서버와 클라이언트의 렌더링 결과가 불일치

 

해결 방법

export const FeatureToggles = () => {
  const [mounted, setMounted] = useState(false);  // 👈 마운트 상태 추가
  const { user } = useAuth();
  const isAdmin = user?.admin === 'true';

  useEffect(() => {
    setMounted(true);  // 👈 클라이언트에서 마운트 완료 시 상태 변경
  }, []);

  return (
    <div>
      {mounted && isAdmin && <Link>글쓰기</Link>}  // 👈 마운트 된 후에만 렌더링
    </div>
  );
};

mounted 상태의 역할

  • 초기값 false

  • 서버 사이드 렌더링 시에는 항상 false

  • 버튼이 렌더링되지 않음

  • 서버와 클라이언트의 초기 렌더링이 일치

  • 클라이언트에서 true로 변경

  • useEffect는 클라이언트에서만 실행

  • 컴포넌트가 마운트된 후 mountedtrue로 변경

  • 이후 조건부 렌더링이 정상적으로 동작

장점

  • 안정적인 hydration

  • 서버와 클라이언트의 초기 렌더링이 일치

  • hydration 에러 방지

  • 클라이언트 사이드 로직이 준비된 후에만 조건부 렌더링 실행

단점

  • 깜빡임

  • 컴포넌트 마운트 후 버튼 표시 가능

  • UX에 영향을 줄 수 있음

관련 글

TypeScript any 린트 에러(no-explicit-any) 근본적으로 해결하기

TypeScript 프로젝트에서 @typescript-eslint/no-explicit-any 린트 에러는 단순 규칙 비활성화로 해결할 문제가 아닙니다. 눈 앞 문제는 해결할 수 있지만, TypeScript를 사용하는 가장 중요한 이유를 위배하게 됩니다. any 타입은...

2025년 7월 23일269

JSP 주석, 아직도 `` 쓰시나요? 올바른 사용법

코드를 작성하다 보면 주석을 남기는 경우가 많습니다. 하지만 JSP 환경에서 어떤 주석을 사용하냐에 따라 보안 수준과 성능 이 크게 달라집니다. 표준 주석: 서버 사이드 주석 &lt;%-- --%&gt; JSP 페이지 내 개발 관련 주석은 &lt;%-- --%&gt; 를 사용하는게 좋습니다...

2025년 7월 9일144

쉽게 만드는 React Tab 라이브러리 react-tabs

개발자가 커스텀 스타일을 쉽게 적용할 수 있도록 최소한의 스타일만 제공하여 유연한 스타일링 이 가능한 라이브러리입니다. 상태 관리가 내장되어 있어 탭 선택 및 패널 표시 로직을 직접 구현할 필요 없이 간편하게 사용할 수 있습니다. 기본 사용법 먼저, 라이브러리를 설치합...

2025년 6월 17일173

Next.js 환경 변수 NEXT_PUBLIC 접두사 역할

NEXT_PUBLIC 접두사를 붙이면 변수의 접근 범위가 완전히 달라집니다. 이 차이점을 이해하는 것이 안전하고 효율적인 Next.js 애플리케이션을 구축하는 데 중요합니다. NEXT_PUBLIC 접두사가 없는 환경 변수 (서버 전용) NEXT_PUBLIC 접두사 없이...

2025년 6월 13일156