Hydration
서버에서 생성한 HTML은 단순 마크업이므로 사용자 인터렉션이 불가능하다.
따라서 React 는 이벤트리스너, 상태관리와 같은 클라이언트 로직을 전달받은 HTML과 통합하여 애플리케이션으로 작동할 수 있도록 한다. 이과정을 `Hydration` 이라 한다.
다시 설명하면,
서버에서 생성한 HTML을 클라이언트에게 전달하고,
클라이언트는 전달받은 HTML에 이벤트리스너와 상태관리와 같은 클라이언트 로직을 연결시킨다. 이것이 `Hydration`이다.
이때 중요한건 연결하는 과정인데,
React는 Element와 로직 정보가 담긴 가상 DOM 을 생성한 뒤 이를 전달받은 HTML과 비교한다.
즉, 서버와 클라이언트 렌더링 결과가 같은 경우에만 `Hydration`을 수행할 수 있다.
function App() {
const name = (() => {
/* 서버 환경인 경우, 객체에 접근하지 못하도록 수정 .. */
if ( isServer() ) {
return null;
}
return new URL(location.href).searchParams.get(name);
})();
/* 유저의 이름을 화면에 출력한다 ..*/
return <div>{name}</div>
}
서버환경일 땐 null 을 리턴하고, 클라이언트 환경이면 브라우저 location객체에서 파라미터 정보를 가져오는 코드이다.
이 코드를 실행하면, 아래와 같은 에러가 난다.
Unhandled Runtime Error Text content does not match server-rendered HTML

위의 `Hydration` 을 이해한다면 에러원인을 알아낼 수 있다.
서버에서는 name 변수의 값은 항상 null 이지만, 클라이언트에서는 쿼리파라미터가 존재하면 그 파라미터값이 name 변수값이 된다.
즉, 서버와 클라이언트는 각각 다른 결과물을 렌더링 하게 되면서 Hydration을 수행할 수 없는 상태가 되어버리는 것이다.
// 서버
<div>{null}</div>
// 클라이언트
<div>{'김토스'}</div>
해결방안
Hydration Mismatch 를 해결하기 위해선, 서버와 클라이언트의 렌더링 결과물이 같아야 한다.
import { useRouter } from 'next/router';
function App() {
const name = useRouter().query.name;
return <div>{name}</div>
}
다행히도, 위의 코드에서 Next.js 의 `useRouter() hook` 을 사용하면 예외처리 없이도 서버,클라이언트 어느 환경에서든 동일한 결과값을 보장받을 수 있다.
// 서버
<div>{'김토스'}</div>
// 클라이언트
<div>{'김토스'}</div>
이처럼 서버와 클라이언트 양측에 동일한 결과를 보장하는 코드를 `isomorphic` 하다고 표현한다.
'🌳Frontend > etc' 카테고리의 다른 글
쿠키, 세션 (2) | 2023.09.10 |
---|---|
[Web] Gzip 압축으로 사이트를 최적화해보자 (0) | 2023.09.06 |
[FE] Next.js SSR 환경에서 흔히 겪는 에러 Server Error XXX is not defined. This error happened while generating the page. (0) | 2023.09.04 |
[FE] 토스가 정의하는 컴포넌트의 역할과 분리 기준 (0) | 2023.09.03 |
[FE] 실무에서 바로 쓰는 Frontend Clean Code (0) | 2023.09.03 |
Hydration
서버에서 생성한 HTML은 단순 마크업이므로 사용자 인터렉션이 불가능하다.
따라서 React 는 이벤트리스너, 상태관리와 같은 클라이언트 로직을 전달받은 HTML과 통합하여 애플리케이션으로 작동할 수 있도록 한다. 이과정을 Hydration
이라 한다.
다시 설명하면,
서버에서 생성한 HTML을 클라이언트에게 전달하고,
클라이언트는 전달받은 HTML에 이벤트리스너와 상태관리와 같은 클라이언트 로직을 연결시킨다. 이것이 Hydration
이다.
이때 중요한건 연결하는 과정인데,
React는 Element와 로직 정보가 담긴 가상 DOM 을 생성한 뒤 이를 전달받은 HTML과 비교한다.
즉, 서버와 클라이언트 렌더링 결과가 같은 경우에만 Hydration
을 수행할 수 있다.
function App() {
const name = (() => {
/* 서버 환경인 경우, 객체에 접근하지 못하도록 수정 .. */
if ( isServer() ) {
return null;
}
return new URL(location.href).searchParams.get(name);
})();
/* 유저의 이름을 화면에 출력한다 ..*/
return <div>{name}</div>
}
서버환경일 땐 null 을 리턴하고, 클라이언트 환경이면 브라우저 location객체에서 파라미터 정보를 가져오는 코드이다.
이 코드를 실행하면, 아래와 같은 에러가 난다.
Unhandled Runtime Error Text content does not match server-rendered HTML

위의 Hydration
을 이해한다면 에러원인을 알아낼 수 있다.
서버에서는 name 변수의 값은 항상 null 이지만, 클라이언트에서는 쿼리파라미터가 존재하면 그 파라미터값이 name 변수값이 된다.
즉, 서버와 클라이언트는 각각 다른 결과물을 렌더링 하게 되면서 Hydration을 수행할 수 없는 상태가 되어버리는 것이다.
// 서버
<div>{null}</div>
// 클라이언트
<div>{'김토스'}</div>
해결방안
Hydration Mismatch 를 해결하기 위해선, 서버와 클라이언트의 렌더링 결과물이 같아야 한다.
import { useRouter } from 'next/router';
function App() {
const name = useRouter().query.name;
return <div>{name}</div>
}
다행히도, 위의 코드에서 Next.js 의 useRouter() hook
을 사용하면 예외처리 없이도 서버,클라이언트 어느 환경에서든 동일한 결과값을 보장받을 수 있다.
// 서버
<div>{'김토스'}</div>
// 클라이언트
<div>{'김토스'}</div>
이처럼 서버와 클라이언트 양측에 동일한 결과를 보장하는 코드를 isomorphic
하다고 표현한다.
'🌳Frontend > etc' 카테고리의 다른 글
쿠키, 세션 (2) | 2023.09.10 |
---|---|
[Web] Gzip 압축으로 사이트를 최적화해보자 (0) | 2023.09.06 |
[FE] Next.js SSR 환경에서 흔히 겪는 에러 Server Error XXX is not defined. This error happened while generating the page. (0) | 2023.09.04 |
[FE] 토스가 정의하는 컴포넌트의 역할과 분리 기준 (0) | 2023.09.03 |
[FE] 실무에서 바로 쓰는 Frontend Clean Code (0) | 2023.09.03 |