리액트, Next를 처음 시작하면 알아야 할 중요한 개념이다.
개발을 하면서도 하이드레이션이 뭔가 느낌이 와닿지 않았다. 그래서 공부해보려고 한다!
Hydration이란 사전적 의미로 수분공급이라고 한다.
처음에 수분공급이라는 말이 너무 문학적인 표현의 용어 같아서 와닿지 않았다ㅋㅋ
또한 하이드레이션은 CSR 서비스에서는 접하기 어렵다.
그래서 신규 프로젝트가 SSR로 작업하게 되면서 하이드레이션 에러도 만나고... 차츰 접하게 되었다.
서버에서 HTML을 생성하여 클라이언트에게 전달하면 이 HTML을 클라이언트가 가지고 있는 HTML(Dom Tree 객체)과의 비교작업 후, 완전 일치할때 다운로드 받은 JS Chunk 파일을 Dom Tree에 연결시켜 인터렉티브 가능한 상태로 만드는 연결 작업이다.
하이드레이션이 완료 된 후, 리액트 클라이언트 측 기능 (클릭, 상태변화 등) 이 동작하게 된다.
✅ 조건1 : 서버에서 생성된 HTML이 있고
✅ 조건2 : React가 클라이언트에서 해당 HTML을 다시 연결해야 하는 경우
즉, React가 클라이언트에서 "이 HTML을 다시 조작할 가능성이 있을 때" Hydration이 발생한다.
정적 HTML
<!DOCTYPE html>
<html>
<head>
<title>정적 페이지</title>
</head>
<body>
<h1>이 페이지는 Hydration이 필요 없음</h1>
</body>
</html>
CSR 으로만 이뤄진 리액트(Next) 애플리케이션
'use client'
const React from 'react'
const CSRApplication = () => {
return <div>안녕하세요</div>
}
output: "export" 사용 (Next.js 13+) 또는 export const runtime = 'edge'; 사용
이 설정을 하면 Next.js는 정적 HTML만 생성하고, React는 실행되지 않으므로 Hydration이 발생하지 않음
{
"output": "export"
}
// 컴포넌트 내에서
export const runtime = 'edge';
export default function Page() {
return <h1>Next.js 정적 페이지</h1>;
}
특정 컴포넌트에서 Hydration 방지 (useEffect)
이렇게 하면 초기 정적 HTML은 렌더링되지만, Hydration이 일어나지 않고 클라이언트에서 다시 렌더링됨
import { useEffect, useState } from "react";
export default function Page() {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
return mounted ? <h1>클라이언트에서만 렌더링</h1> : <h1>정적 HTML</h1>;
}
웹애플리케이션이 빠르게 성장하면서 SPA 웹의 사용이 증가하였고, SPA 와 궁합이 잘 맞는 CSR 렌더링 기법이 주로 사용되었다.
그러나 CSR의 한계로 이를 극복하기 위해 SSR 도입이 필요하였고, 이 과정에서 리액트는 하이드레이션이라는 기술을 탄생시켰다.
CSR(Client-Side Rendering) 방식이란?
- 사용자가 브라우저에서 페이지를 요청하면, 서버는 빈 HTML과 JavaScript 번들 파일을 보냄.
- 브라우저가 JavaScript를 다운로드하고 실행해야 화면을 렌더링할 수 있음.
- 모든 DOM 요소와 이벤트 핸들러가 클라이언트에서 생성됨.
사용자에게 빈 HTML 을 먼저 보내고 이후 JS 가 실행되고 렌더링 되므로, 첫화면이 보이기까지 오래 걸리는 문제점이 있다.
검색엔진은 페이지를 크롤링할 때 HTML 을 분석하는데, CSR 방식에서는 HTML이 빈 상태이기 때문에 SEO에 불리하다.
모든 렌더링이 클라이언트에서만 이루어지므로, 서버는 단순한 정적 파일 제공자 역할만 하게 된다.
SSR(Server-Side Rendering) 방식이란?
- 사용자가 브라우저에서 페이지를 요청하면 서버가 실제 HTML을 만들어서 반환
- 브라우저는 HTML 을 즉시 렌더링
SSG(Static-Site-Generation) 이란?
- 미리 빌드 시점에 HTML을 생성하여 정적 파일로 배포
- 사용자가 요청 즉시 HTML을 제공하므로 가장 빠르다.
리액트는 이벤트핸들러, 상태 등 인터렉티브 기능들이 모두 Client-Side에서 동작해야 한다.
따라서 CSR 한계를 극복하기 위해 SSR, SSG가 나오게 되었고 인터렉티브 기능까지 동작하게 하기위해 Hydration 과정을 도입하게 되었다.
Q1. 인터렉티브 코드가 없으면 Hydration은 일어나지 않는가?
export default function Page() {
return <h1>Next.js 정적 페이지</h1>;
}
Answer
Next.js 같은 경우 기본적으로 모든 페이지를 React 애플리케이션으로 간주한다.
위에 코드도 React 컴포넌트이며, 서버에서 HTML을 받아 전달 되었다면 인터렉티브가 없어도 리액트는 이를 클라이언트에서 다시 연결해야 된다고 판단한다.
Q2. 그럼 리액트 관리 코드는 모두 Hydration이 일어나는가?
Answer
React가 모든 페이지를 관리한다고 해서 Hydration이 항상 일어나는 것은 아니다.
React가 관리하는 방식에 따라 3가지 경우로 나눌 수 있다.

서버에서 HTML을 미리 만들지 않고 클라이언트에서 React가 처음부터 렌더링한다면 하이드레이션이 발생하지 않는다.