NextJS / / 2024. 11. 29. 06:00

RSC vs RCC

RSC (React Server Component)

  • RSC는 React Server Component의 줄임말입니다.
  • 서버 컴포넌트라고 불리며, 이는 React 18부터 도입된 개념으로, 컴포넌트를 서버에서 렌더링하고 그 결과를 클라이언트로 전달합니다.
  • 서버 컴포넌트의 특징:예를 들어, 서버 컴포넌트는 데이터베이스와의 통신, API 호출 등을 통해 데이터를 가져와 클라이언트에게 미리 HTML 형태로 전달할 수 있습니다. 이 과정에서 브라우저에 불필요한 JavaScript가 줄어들기 때문에 초기 로딩 속도를 개선할 수 있습니다.
    • 클라이언트로 전달할 HTML을 서버에서 미리 생성합니다. 이는 서버의 리소스를 활용해서 클라이언트의 부담을 줄이는 데 도움이 됩니다.
    • 서버 컴포넌트에서는 상태 관리 훅(useStateuseEffect 등)을 사용할 수 없으며, 브라우저 전용 API도 사용할 수 없습니다. 대신 데이터를 가져오거나, 백엔드와 직접 통신하는 작업에 적합합니다.
    • 일반적으로 비동기 데이터 로딩에 용이하고, 초기 페이지 로딩 성능을 개선하는 데 도움이 됩니다.

RCC (React Client Component)

  • RCC는 React Client Component의 줄임말입니다.
  • 클라이언트 컴포넌트라고 불리며, 기존에 우리가 흔히 사용하던 방식의 React 컴포넌트를 의미합니다.
  • 클라이언트 컴포넌트의 특징:
    • 브라우저에서 실행되며, 사용자와의 상호작용을 처리하기 위한 이벤트 핸들러(onClickonChange 등)를 사용합니다.
    • 상태 관리(useStateuseEffect 등) 및 브라우저 API (localStoragewindow 등)를 활용할 수 있습니다.
    • 클라이언트 컴포넌트는 'use client' 지시어를 사용해 명시할 수 있으며, 이를 통해 명확하게 클라이언트에서 렌더링해야 하는 컴포넌트임을 나타냅니다.

클라이언트 컴포넌트는 사용자가 클릭하거나 스크롤하는 등 상호작용을 다룰 수 있어야 하는 UI 부분에 주로 사용됩니다. 브라우저와의 상호작용이 필요한 컴포넌트들은 클라이언트 컴포넌트로 작성됩니다.

RSC와 RCC의 차이점

  1. 렌더링 위치:
    • RSC: 서버에서 렌더링합니다. 이 컴포넌트는 데이터 처리를 서버 측에서 수행하고, 클라이언트에 결과만 보내줍니다.
    • RCC: 브라우저에서 렌더링합니다. 클라이언트에서 사용자와의 상호작용을 처리합니다.
  2. 상태 및 이벤트 처리:
    • RSC: 상태나 이벤트 처리 관련 훅(useStateuseEffect)을 사용할 수 없습니다.
    • RCC: 상태 관리와 이벤트 처리를 위해 여러 가지 React 훅을 사용할 수 있습니다.
  3. 사용 예:
    • RSC: 백엔드와 통신하는 데이터 로딩, 초기 렌더링에서 복잡한 JavaScript 계산을 서버에서 처리하고 싶을 때.
    • RCC: 사용자의 입력, 버튼 클릭, 상호작용 등 클라이언트 쪽에서 사용자 경험을 개선하는 데 사용.

예시 코드

아래는 두 종류의 컴포넌트를 비교한 간단한 예시입니다.

React Server Component (RSC):

// 서버 컴포넌트
export default async function ServerComponent() {
    const data = await fetchData();// 서버에서 데이터를 가져옴
    return (
        <div>
            <h1>서버에서 데이터를 렌더링합니다.</h1>
            <p>{data}</p>
        </div>
    );
}

React Client Component (RCC):

'use client';

import { useState } from 'react';

// 클라이언트 컴포넌트
export default function ClientComponent() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <h1>클라이언트에서 카운터를 사용합니다.</h1>
            <button onClick={() => setCount(count + 1)}>
                Count: {count}
            </button>
        </div>
    );
}

이렇게 RSC와 RCC는 각각 서버와 클라이언트에서 수행하는 역할에 맞게 사용됩니다. 서버에서 미리 데이터를 준비해 최적화된 HTML을 제공하거나 클라이언트 측에서 필요한 상호작용을 다룰 수 있도록 컴포넌트를 구분함으로써 전체 웹 애플리케이션의 성능을 개선하는 데 큰 도움이 됩니다.

Server Component vs Client Component

  1. 데이터 가져오기 (Fetch data)
    • 서버 컴포넌트: 가능 (✅)
    • 클라이언트 컴포넌트: 불가능 (❌)
  2. 백엔드 리소스에 직접 접근하기 (Access backend resources directly)
    • 서버 컴포넌트: 가능 (✅)
    • 클라이언트 컴포넌트: 불가능 (❌)
  3. 서버에서 민감한 정보 유지하기 (Access tokens, API keys 등)
    • 서버 컴포넌트: 가능 (✅)
    • 클라이언트 컴포넌트: 불가능 (❌)
  4. 서버에서 큰 종속성 유지하기 / 클라이언트 측 자바스크립트 줄이기 (Keep large dependencies on the server / Reduce client-side JavaScript)
    • 서버 컴포넌트: 가능 (✅)
    • 클라이언트 컴포넌트: 불가능 (❌)
  5. 상호작용 추가 및 이벤트 리스너 추가 (Add interactivity and event listeners, 예: onClick(), onChange() 등)
    • 서버 컴포넌트: 불가능 (❌)
    • 클라이언트 컴포넌트: 가능 (✅)
  6. 상태와 생명주기 효과 사용 (Use State and Lifecycle Effects, 예: useState(), useReducer(), useEffect() 등)
    • 서버 컴포넌트: 불가능 (❌)
    • 클라이언트 컴포넌트: 가능 (✅)
  7. 브라우저 전용 API 사용 (Use browser-only APIs)
    • 서버 컴포넌트: 불가능 (❌)
    • 클라이언트 컴포넌트: 가능 (✅)
  8. 상태, 효과, 브라우저 전용 API에 의존하는 커스텀 훅 사용 (Use custom hooks that depend on state, effects, or browser-only APIs)
    • 서버 컴포넌트: 불가능 (❌)
    • 클라이언트 컴포넌트: 가능 (✅)
  9. React 클래스 컴포넌트 사용 (Use React Class components)
    • 서버 컴포넌트: 불가능 (❌)
    • 클라이언트 컴포넌트: 가능 (✅)

use client

코드 예제 설명

이미지에는 두 개의 TypeScript 파일 (**app/page.tsx**와 app/gallery.tsx)의 코드가 나타나 있는데, 아래에 각각을 설명해 보겠습니다.

첫 번째 코드 (app/page.tsx)

  1. import { Carousel } from 'acme-carousel';
    • Carousel 컴포넌트를 가져옵니다. 이 컴포넌트는 클라이언트에서 렌더링해야 하는 UI 요소입니다.
  2. 함수 컴포넌트 Page 정의
    • 이 컴포넌트는 서버 컴포넌트로 사용되며, 상태 관리 로직이 사용되지 않았습니다.
    • 여기서 중요한 점은 서버 컴포넌트는 React의 상태나 생명주기 훅을 사용할 수 없다는 것입니다. 예를 들어 useState 같은 훅을 사용할 경우 오류가 발생하게 됩니다.
    • 따라서 클라이언트 전용 상호작용이 필요한 컴포넌트 (Carousel 같은)를 서버 컴포넌트에서 직접 사용하려고 하면 오류가 발생합니다.
  3. export default function Page() { return ( <div> <p>View pictures</p> {/* 오류: useState는 서버 컴포넌트 내에서 사용될 수 없음 */} <Carousel /> </div> ); }

두 번째 코드 (app/gallery.tsx)

  1. 'use client' 지시문 추가
    • 파일의 최상단에 **'use client'**를 추가하여 이 컴포넌트가 클라이언트 컴포넌트로 동작하도록 명시합니다.
    • 이를 통해 클라이언트 측에서만 실행되어야 하는 훅(useState)을 사용할 수 있습니다.
  2. 'use client';
  3. 클라이언트 전용 컴포넌트 구현
    • useState 사용useState(false)를 사용하여 상태(isOpen)를 관리합니다. 이 상태는 버튼 클릭에 따라 변화합니다.
    • <button onClick={() => setIsOpen(true)}>View pictures</button>: 버튼 클릭 시 상태가 변경되어 **isOpen**이 **true**로 설정됩니다.
    • 조건부 렌더링: 상태에 따라 <Carousel /> 컴포넌트가 렌더링됩니다.
    • 'use client' 지시문이 있기 때문에 **useState**와 같은 훅을 사용할 수 있고, 사용자와의 상호작용도 클라이언트 측에서 처리할 수 있습니다.
  4. import { useState } from 'react'; import { Carousel } from 'acme-carousel'; export default function Gallery() { let [isOpen, setIsOpen] = useState(false); return ( <div> <button onClick={() => setIsOpen(true)}>View pictures</button> {/* 클라이언트 컴포넌트에서 Carousel 사용 가능 */} {isOpen && <Carousel />} </div> ); }

결론

  • 서버 컴포넌트는 데이터를 가져오거나 서버와 관련된 처리를 담당할 수 있지만, 클라이언트 측 상태 관리나 브라우저 전용 API를 사용할 수 없습니다.
  • 클라이언트 컴포넌트로 명시하려면 최상단에 'use client' 지시문을 추가해야 합니다. 이를 통해 React의 상태와 같은 클라이언트 측에서만 필요한 기능들을 사용할 수 있습니다.
  • 클라이언트 컴포넌트는 브라우저와의 상호작용이 필요한 경우, 상태 관리 훅이나 이벤트 핸들러 등을 자유롭게 사용할 수 있습니다.

'NextJS' 카테고리의 다른 글

NextJS Hook정리  (1) 2024.11.30
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유