본문 바로가기

Next.js

Next.js 10-5 React Essential Context

  • 서버 컴포넌트에서 타사 컨텍스트 공급자 렌더링

  타사 npm 패키지에는 애플리케이션 루트 근처에서 렌더링해야 하는 공급자가 포함되는 경우가 많다. 이러한 공급자가 'use client' 지시문을 포함하는 경우에는 서버 컴포넌트에서 직접 렌더링 하는데 문제가 없다. 그러나 서버 컴포넌트는 새로운 개념이기 때문에 많은 타사 공급자가 아직 지시문을 추가하지 않았을 확률이 높다. 결국 'use client' 지시문이 없는 타사 공급자를 렌더링 하려고 하면 오류가 난다.

import { ThemeProvider } from 'acme-theme';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {/* Error: `createContext` can't be used in Server Components */}
      </body>
    </html>
  )
}

  이 문제를 해결하기 위해 고유한 클라이언트 컴포넌트에 타사 공급자를 매핑하면 된다.

'use client';

import { ThemeProvider } from 'acme-theme'
import { AuthProvider } from 'acme-auth'

export function Providers({ children }) {
  return (
    <ThemeProvider>
      <AuthProvider>{children}</AuthProvider>
    </ThemeProvider>
  )
}

  이제 <Providers />를 루트 레이아웃 내에서 직접 가져오고 렌더링 할 수 있다.

import { Providers } from './providers';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}

  루트에서 렌더링 된 공급자를 사용하면 이러한 라이브러리의 모든 컴포넌트와 hook이 고유한 클라이언트 컴포넌트 내에서 잘 작동한다. 타사 라이브러리가 'use client' 지시문을 클라이언트 코드에 추가되면 래퍼 클라이언트 컴포넌트를 제거할 수 있다.

 

  • 서버 컴포넌트 간에 데이터 공유하기

  서버 컴포넌트는 대화형이 아니므로 React 상태에서 읽지 않으므로 데이터를 공유하기 위해 컨텍스트의 모든 권한이 필요하지 않는다. 여러 서버 컴포넌트가 액세스해야 하는 공통 데이터가 있는 경우 모듈 범위 내에서 전역 싱글톤과 같은 기본 JavaScript 패턴을 사용할 수 있다.

  예를 들어 모듈을 사용하여 여러 컴포넌트에서 데이터베이스 연결을 공유할 수 있다.

// utils/database.ts

export const db = new DatabaseConnection();
// app/users/layout.tsx

import { db } from '@utils/database

export async function UsersLayout() {
  let users = await db.query();
  // ...
}
// app/users/[ID]/page.tsx

import { db } from '@utils/database';

export async function DashboardPage() {
  let user = await db.query()
  // ...
}

  위의 예에서 레이아웃과 페이지 모두 데이터베이스 쿼리를 만들어야 한다. 이러한 각 컴포넌트는 @utils/database 모듈을 가져옴으로써 데이터베이스에 대한 액세스를 공유한다.

 

  • 서버 컴포넌트 간에 fetch request 공유

  데이터를 가져올 때 페이지 또는 레이아웃과 일부 하위 컴포넌트 간에 fetch 결과를 공유할 수 있다. 그러나 이것은 컴포넌트 간의 불필요한 연결이며 컴포넌트 간에 props가 앞뒤로 전달될 수 있다.

  그래서 대신에 데이터를 소비하는 컴포넌트와 함께 데이터 fetch를 함께 배치하는 것이 좋다. fetch 요청은 서버 컴포넌트에서 자동으로 중복 제거되므로 각 경로 세그먼트는 중복 요청에 대한 걱정 없이 필요한 데이터를 정확하게 요청할 수 있다. Next.js는 fetch 캐시에서 동일한 값을 읽는다.