Header Banner
GG Logo

Future Engineering

기술의 최전선을 기록합니다.

기술 자료/FrontEnd/Hydration Error와 mounted 상태 관리에 대한 설명

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

FrontEnd5개월 전

문제 상황

// 문제가 있는 코드
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에 영향을 줄 수 있음

Hydration Error와 mounted 상태 관리에 대한 설명 | TECH.KAKAO.GG