본문 바로가기

Next.js

Next.js 10-3 React Essential 타사 패키지 사용

  • 서버 및 클라이언트 컴포넌트를 언제 사용할까?

  서버와 클라이언트 컴포넌트 사이의 결정을 단순화하려면 app 클라이언트 컴포넌트에 대한 사용 사례가 있을 때까지 서버 컴포넌트(디렉토리의 기본값) 사용하는 것이 좋다.

원하는 작동 서버 컴포넌트 클라이언트 컴포넌트
데이터 가져오기 O X
백엔드 리소스에 액세서(직접적) O X
민감한 정보를 서버에 보관(액세스 토큰 API  ) O X
서버에 대한  종속성 유지/클라이언트  JavaScript 감소 O X
상호 작용  이벤트 리스너( onClick(), onChange() 추가 X O
상태  수명 주기 효과 사용 ( useState(), useReducer(), useEffect(), ) X O
브라우저 전용 API 사용 X O
상태효과 또는 브라우저 전용 API 의존하는 custom hook 사용 X O
React Class Component 사용 X O

 

  클라이언트 컴포넌트에서 데이터를 가져올 수 있지만 클라이언트에서 데이터를 가져와야 하는 특별한 이유가 없는 한 서버 컴포넌트에서 데이터를 가져오는 것이 좋다. 데이터 가져오기를 서버로 이동하면 성능과 경험이 향상된다.

 

  • 타사 패키지 사용하기

  서버 컴포넌트가 새로운 개념이기 때문에 생태계의 타사 패키지는 useState, useEffect 및 createContext와 같은 클라이언트 전용 기능을 사용하는 컴포넌트가 많다. 이 경우에 'use client'라는 지시문을 추가해줘야 한다.

  그러나 현재 클라이언트 전용 기능을 사용하는 npm 패키지의 많은 컴포넌트에는 아직 지시문이 없는 경우가 많다. 이러한 타사 컴포넌트는 'use client' 지시문을 사용하면 자체 클라이언트 컴포넌트 내에서는 예상대로 작동하지만 서버 컴포넌트 내에서는 작동하지 않을 수 있다.

  예를 들어 <AcmeCarousel />  컴포넌트가 있는 가상 acme-carousel 패키지를 설치했다고 하자. 이 컴포넌트는 useState를 사용하지만 아직 'use client' 지시문이 없다. 그 경우 아래와 같이 클라이언트 컴포넌트 내에서 사용하면 잘 작동된다.

'use client';

import { useState } from 'react';
import { AcmeCarousel } from 'acme-carousel';

export default function Gallery() {
  let [isOpen, setIsOpen] = useState(false);
  
  return (
    <div>
      <button onClick={() =>  setIsOpen(true)}>View pictures</button>
      
      {/* Works, since AcmeCarousel is used within a Client Component */}
      {isOpen && <AcmeCarousel />}
    </div>
  )
}

  그러나 서버 컴포넌트 내에서 직접 사용하려고 하면 오류가 날 것이다.

import { AcmeCarousel } from 'acme-carousel'

export default function Page() {
  return (
    <div>
      <p>View pictures</p>
      
      {/* Error: `useState` can not be used within Server Components */}
      <AcmeCarousel />
    </div>
  )
}

  이것은 Next.js가 <AcmeCarousel />이 클라이언트 전용 기능을 사용하고 있는지 모르기 때문이다. 이 문제를 해결하려면 고유한 클라이언트 컴포넌트에서 클라이언트 전용 기능에 의존하는 타사 컴포넌트를 래핑해야 한다.

'use client'

import { AcmeCarousel } from 'acme-carousel';

export default AcmeCarousel;

  이제 <Carousel />을 서버 컴포넌트 내에서 직접 사용할 수 있다.

import Carousel from './carousel';

export default function Page() {
  return (
    <div>
      <p>View pictures</p>
      
      {/* Works, since Carousel is a Client Component */}
      <Carousel />
    </div>
  )
}

 

  대부분의 타사 컴포넌트를 클라이언트 컴포넌트 내에서 사용할 가능성이 높기 때문에 래핑을 할 필요는 없다. 그러나 한 가지 예외로 공급자 컴포넌트가 있다. 이는 React 상태 및 컨텍스트에 의존하고 일반적으로 애플리케이션의 루트에 필요하지 않기 때문이다.