avatar
sanghyeon.dev.log
server component in client component
서버 컴포넌트를 여기 저기서 사용해보자
nextjs
Jul 17
·
4 min read

Next.js App Router에서 컴포넌트는 기본적으로 모두 서버 컴포넌트로 동작합니다. 클라이언트 컴포넌트를 사용하려면 컴포넌트 상단에 use client라는 특별한 예약어를 선언해야 합니다. use client를 선언하면 해당 컴포넌트부터 아래 트리까지 클라이언트 경계(Client Boundary)가 형성되어, 그 아래 모든 컴포넌트는 클라이언트 컴포넌트로 동작합니다.

클라이언트 컴포넌트에서 import되는 모듈과 컴포넌트는 모두 클라이언트에서 동작합니다. 서버 컴포넌트 아래에는 클라이언트 컴포넌트가 포함될 수 있으며, 클라이언트 컴포넌트 아래에도 클라이언트 컴포넌트가 포함될 수 있습니다.
그러나 클라이언트 컴포넌트 아래로 서버 컴포넌트가 들어갈 수는 없습니다.

다음은 서버 컴포넌트와 클라이언트 컴포넌트의 예시입니다

'use client';

export const ClientComponent = () => {
  return (
    <div>
      <h1>Client Component</h1>
    </div>
  );
};
import React from 'react';

export const ServerComponent = async () => {
  const data = await getData();
  return <div>{JSON.stringify(data)}</div>;
};

async function getData() {
  const res = await fetch('<https://jsonplaceholder.typicode.com/todos/1>');
  const json = await res.json();

  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }

  return json;
}

export default ServerComponent;

동작하지 않는 패턴

"use client";

import ServerComponent from './ServerComponent';

export const ClientComponent = () => {
  return (
    <div>
      <h1>Client Component</h1>
      <ServerComponent />
    </div>
  );
};
const App = () => {
  return (
    <ClientComponent />
  )
}

그렇다면 서버 컴포넌트를 클라이언트 컴포넌트 아래에서 사용하려면 어떻게 해야 할까요?
현재 유일한 방법은 클라이언트 컴포넌트에게 서버 컴포넌트를 props로 넘기는 것입니다.

동작하는 패턴

'use client';

export const ClientComponent = ({ children }: { children: React.ReactNode }) => {
  return (
    <div>
      <h1>Client Component</h1>
      {children}
    </div>
  );
};
const App = () => {
  return (
    <ClientComponent>
      <ServerComponent />
    </ClientComponent>
  )
}

위에서 use client를 선언하면 해당 컴포넌트로부터 아래 트리에 Client Boundary가 생성된다고 했습니다. Client Boundary에서 중요한 것은 컴포넌트의 부모-자식 관계가 아니라 어디서 import되었느냐입니다. 동작하는 패턴의 예제에서 ServerComponent는 서버 컴포넌트로써 동작하는 App에서 import되었습니다.

ClientComponent는 단순히 props로 받은 children이 어디서 렌더링될지 알 뿐, 어떤 컴포넌트가 올지는 모릅니다. 이러한 패턴을 통해 Layout에 use client로 선언된 Provider 등으로 감싸져 있어도 서버 컴포넌트를 사용할 수 있습니다.

참조
https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns
https://www.youtube.com/watch?si=6SwhGCoYwEgKkuwS&v=vjBQks_tjOA&feature=youtu.be


- 컬렉션 아티클







안녕하세요