“hydration” 에러는 서버에서 렌더링된 HTML과 클라이언트에서 렌더링된 HTML이 일치하지 않을 때 발생합니다. 이를 이해하려면 서버 사이드 렌더링(SSR)과 클라이언트 사이드 렌더링(CSR)에 대한 이해가 필요합니다.
서버 사이드 렌더링(SSR)과 클라이언트 사이드 렌더링(CSR)
1. 서버 사이드 렌더링(SSR):
• SSR에서는 서버에서 초기 HTML을 생성하여 클라이언트(브라우저)로 전달합니다.
• 이렇게 하면 사용자는 빠르게 초기 페이지를 볼 수 있으며, 검색 엔진 최적화(SEO)에도 유리합니다.
• Next.js는 기본적으로 SSR을 지원합니다.
2. 클라이언트 사이드 렌더링(CSR):
• CSR에서는 브라우저가 JavaScript를 통해 페이지를 렌더링합니다.
• 초기에는 빈 HTML이 로드되고, JavaScript가 로드된 후에 페이지가 완전히 렌더링됩니다.
• React는 CSR을 기본적으로 사용합니다.
hydration 과정
hydration은 SSR을 사용하여 서버에서 생성된 HTML을 클라이언트에서 React 컴포넌트로 “활성화”하는 과정입니다. 이 과정에서 서버에서 생성된 HTML과 클라이언트에서 생성된 HTML이 일치해야 합니다. 일치하지 않으면 React는 클라이언트에서 렌더링된 HTML로 서버에서 렌더링된 HTML을 대체하게 됩니다. 이는 “hydration” 에러를 일으킬 수 있습니다.
예시로 이해하기
1. 서버에서 생성된 HTML:
서버에서 사용자 이름을 렌더링하여 HTML을 생성했다고 가정해 봅시다.
<div id="root">
<p>안녕하세요, 사용자님!</p>
</div>
2. 클라이언트에서 생성된 HTML:
• 클라이언트에서 React가 렌더링하는 동안 사용자 이름이 아직 로드되지 않았다고 가정해 봅시다.
<div id="root">
<p>로딩 중...</p>
</div>
위와 같이 서버에서 렌더링된 HTML과 클라이언트에서 렌더링된 HTML이 다를 경우 React는 “hydration” 에러를 발생시킵니다.
에러가 발생하는 이유
• 서버에서 제공된 HTML이 클라이언트에서의 초기 상태와 다르기 때문에 클라이언트에서 HTML을 다시 렌더링해야 합니다.
• 이 과정에서 일관성이 없으면 React는 오류를 던지고, 서버에서 렌더링된 HTML을 클라이언트에서 다시 렌더링하여 교체하게 됩니다.
해결 방법
1. 동일한 초기 상태 유지:
• 서버와 클라이언트가 동일한 초기 상태를 가지도록 합니다.
• 클라이언트에서 상태를 로드하기 전까지는 서버와 동일한 초기 값을 유지합니다.
2. 조건부 렌더링 사용:
• 클라이언트에서 필요한 데이터를 모두 로드할 때까지 조건부 렌더링을 사용하여 서버와 클라이언트의 HTML이 일치하도록 합니다.
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
return (
<div>
{isMounted ? (
<p>{userInfo ? `안녕하세요, ${userInfo.nickname}님!` : '로딩 중...'}</p>
) : (
<p>로딩 중...</p>
)}
</div>
);
결론
hydration 에러는 서버에서 렌더링된 HTML과 클라이언트에서 렌더링된 HTML이 일치하지 않을 때 발생합니다. 이를 해결하려면 서버와 클라이언트의 초기 상태를 일치시키고, 클라이언트에서 필요한 데이터를 로드할 때까지 조건부 렌더링을 사용하여 일관성을 유지해야 합니다.