인프런 커뮤니티 질문&답변

강혁준님의 프로필 이미지

작성한 질문수

한 입 크기로 잘라먹는 Next.js(15+)

클라이언트 컴포넌트가 서버에서 어떻게 렌더링되는지 궁금합니다!

해결된 질문

24.09.10 23:05 작성

·

94

·

수정됨

0

초기 접속 요청을 할 때, Next.js에서는 서버 컴포넌트와 클라이언트 컴포넌트 모두 사전 렌더링을 한 후에 html을 제공하고 이후 Hydration 과정이 이루어지는 것으로 알고 있습니다.

만약 클라이언트 컴포넌트에서 useState와 같은 훅을 호출해서 사용하는 경우, 서버에서 이런 컴포넌트를 어떻게 렌더링하는지 궁금합니다.

 

최상위 page 컴포넌트가 아래와 같이 있고,


// page.tsx
import Client from "@/components/client";

export default function Home() {
  return (
    <div>
      initial html
      <div>
        <Client />
      </div>
    </div>
  );
}

 

page 컴포넌트에서 불러오는 클라이언트 컴포넌트가 아래와 같을 때

"use client";

import { useState } from "react";

export default function Client() {
  const [count, setCount] = useState(0);

  const handleClickPlusButton = () => {
    setCount(count + 1);
  };

  const handleClickMinusButton = () => {
    setCount(count - 1);
  };

  return (
    <div>
      I am Client Component
      <div>count: {count}</div>
      <div>
        <button onClick={handleClickPlusButton}>+</button>
        <button onClick={handleClickMinusButton}>-</button>
      </div>
    </div>
  );
}

 

서버에서 클라이언트 컴포넌트를 렌더링 할 때, useState와 같은 훅을 무시하고 렌더링을 진행한다고 생각하여 count에 값이 없을 것이라고 예상을 했지만, 서버에서 초기에 응답해준 html 파일을 보면 count가 0이 되어있었습니다.

서버에서 클라이언트 컴포넌트를 렌더링 할 때 이런 훅을 어떻게 처리하는지, 또 만약 브라우저의 window 객체에 접근하게 될 때는 어떻게 처리하는지 궁금합니다!

 

 

답변 2

1

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

2024. 09. 11. 11:21

안녕하세요 혁준님 이정환입니다.

날카로운 질문 감사합니다. 서버측에서 사전렌더링을 진행할때 클라이언트 컴포넌트의 useState 훅은 기본값으로 초기화 된다고 합니다. 따라서 useState(0) 이라고 하여 0이라는 값으로 state의 값을 초기화 해 두셨다면 사전 렌더링시 이 state의 값은 0으로 고정됩니다.

추가로 window 객체는 Page Router 버전과 동일하게 반드시 조건문과 함께 사용하셔야 합니다. 클라이언트 컴포넌트라고 할 지라도 사전 렌더링을 수행하기 위해 서버측에서 실행되기 때문에 아무런 조건문도 없이 window 객체를 활용하게 되면 오류가 발생하게 됩니다.

강혁준님의 프로필 이미지
강혁준
질문자

2024. 09. 11. 14:14

감사합니다 정환님!

0

인프런 AI 인턴님의 프로필 이미지

2024. 09. 10. 23:11

안녕하세요, 인프런 AI 인턴입니다.

강혁준님의 Next.js에서 클라이언트 컴포넌트의 사전 렌더링과 훅 처리에 관한 질문에 대해, 유사한 질문을 한 수강생들에게 제공된 기존 답변을 바탕으로 도움을 드리고자 합니다.

사전 렌더링 및 Hydration과정에서 클라이언트 컴포넌트가 어떻게 처리되는지에 대한 기본적인 설명은, “nextjs 프리패칭” 에 관한 질문에서 찾아볼 수 있습니다. 이 자료는 Next.js에서 페이지 이동 시에 프리패칭된 JS 번들로 수화과정이 진행되고, 이를 통해 클라이언트 사이드에서의 상호작용이 가능해지는 과정을 설명하는데 도움이 됩니다. 해당 내용은 nextjs 프리패칭 질문에서 확인하실 수 있습니다.

서버에서 클라이언트 컴포넌트를 렌더링함에 있어 useState와 같은 훅을 어떻게 처리하는지에 대해 구체적으로 설명하진 않지만, 기본적으로 서버 사이드 렌더링에서 React 훅은 렌더링 시점의 초기값을 기준으로 HTML을 생성하게 됩니다. 클라이언트 컴포넌트 특유의 동작(예: useState가 반영되어 상태 변경이 있을 경우)은, 클라이언트 사이드에서 JS 번들이 로드되고 나서, 즉 Hydration 과정이 완료된 후에야 전체적으로 반영됩니다.

서버 사이드 렌더링 중 window 객체와 같은 브라우저 전용 객체에 접근하는 경우, 일반적으로 이는 서버 사이드에서는 정의되어 있지 않기 때문에 오류를 발생시킬 수 있습니다. 이러한 상황을 처리하기 위해서는 해당 코드가 클라이언트 사이드에서만 실행되도록 처리하는 조건문(예: if (typeof window !== "undefined"))을 사용해야 합니다.

만약 질문자님이 직면한 상황이 보다 구체적인 클라이언트 사이드의 처리 방법, 특히 Next.js에서 서버 사이드 렌더링과 클라이언트 사이드 렌더링의 상호작용에 대해 더 깊이 이해하고자 한다면, 위에서 언급한 질문 외에도 Next.js 관련 문서나 커뮤니티에서 제공하는 추가 자료를 참고하시는 것도 좋을 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.