2025-05-24
Next.js에서 use client 디렉티브를 사용하다 보면, 실제 동작 방식에 대해 헷갈리는 부분이 생깁니다. 이번 기회에 직접 테스트와 공식 문서를 바탕으로 use client를 사용할 때 마주치는 의문점들을 정리해 보았습니다.
use client를 붙였는데도 window is not defined, document is not defined, 혹은 hydration 오류가 나는 이유는?'use client' lets you mark what code runs on the client.
The 'use client' directive declares an entry point for the components to be rendered on the client side and should be used when creating interactive user interfaces (UI) that require client-side JavaScript capabilities, such as state management, event handling, and access to browser APIs. This is a React feature.
즉, 이 지시어는 React가 해당 컴포넌트를 클라이언트 전용으로 다루게 하는 경계선 역할을 한다고 설명되어있습니다.
Next.js는 페이지를 미리 HTML로 만들어 응답하는 프리렌더링(SSG/SSR) 기능을 제공합니다. 이 과정에서 use client가 붙은 클라이언트 컴포넌트도 프리렌더에 사용됩니다.
Client Components and the RSC Payload are used to prerender HTML.
즉, use client를 붙였더라도, 프리렌더링 과정에서는 JSX 구조와 상태 초기값 등이 해석되며 HTML 생성에 사용되므로, 클라이언트 컴포넌트도 ssr에 관여한다고 볼 수 있습니다.
https://nextjs.org/docs/app/getting-started/server-and-client-components#on-the-server
use client가 선언된 클라이언트 컴포넌트도 서버에서 프리랜더되어 HTML에 포함됩니다.
이때 useState는 클라이언트에서만 동작하지만, 프리랜더 시점에서는 초기값이 그대로 사용되어 HTML에 포함된다는 점을 확인할 수 있습니다.
window is not defined or document is not defined"use client";
const [ width ] = useState(() => window.innerWidth);
Next.js는 초기 요청 시 HTML을 만들기 위해 컴포넌트를 서버에서 프리렌더링합니다. 이때 useState의 초기값으로 window 또는 document를 참조하면, 서버에는 없기 때문에 에러가 발생합니다.
Hydration failed because the server rendered HTML didn't match the client"use client";
const [ time ] = useState(() => new Date());
서버에서 new Date()가 실행되어 생성된 시간으로 만들어진 html과, 클라이언트에서 하이드레이션될 때 생성된 시간이 달라질 수 있기 때문에, 하이드레이션 실패가 발생합니다.
이런 문제를 피하려면 다음과 같은 방법을 사용합니다.
useEffect를 사용하여 클라이언트 전용 코드를 실행합니다.typeof window !== "undefined"로 분기합니다. (주의!, 이 방법도 hydration 오류를 일으킬 수 있습니다.)next/dynamic으로 ssr을 비활성화합니다.클라이언트 컴포넌트도 서버에서 랜더링이 되는가?
use client가 붙은 컴포넌트는 클라이언트에서 렌더링됩니다. 즉, 상태 관리, 이벤트 처리, 렌더링 등 모든 동작은 브라우저에서 수행됩니다.use client를 붙였는데도 window is not defined, document is not defined, 혹은 hydration 오류가 나는 이유는?
use client는 해당 컴포넌트를 클라이언트에서만 동작하게 만드는 선언입니다.useState 초기값 등이 서버에서 실행되어 HTML 생성에 사용됩니다.window, document, Date 등을 초기값에서 사용하면 오류 또는 하이드레이션 실패가 발생할 수 있습니다.