시작하기 - React 요점

Zense·2023년 8월 8일
0

Next.js Docs 번역

목록 보기
4/14
post-custom-banner

React 요점

Next.js로 애플리케이션을 구축하려면 Server Component와 같은 React의 최신 기능에 익숙해지는 것이 도움이 됩니다. 이 페이지에서는 Server ComponentClient Component의 차이점, 사용 시기 및 권장 패턴을 살펴봅니다.

React를 처음 사용하는 경우 React Docs도 참조하는 것이 좋습니다. 다음은 React 학습을 위한 좋은 자료입니다.


Server Component

서버 및 클라이언트 컴포넌트를 사용하면 개발자가 서버와 클라이언트에 걸쳐 있는 애플리케이션을 구축하여 클라이언트 사이드 앱의 풍부한 상호 작용과 기존 서버 렌더링의 향상된 성능을 결합할 수 있습니다.

Server Component로 생각하기

React가 UI 구축에 대한 생각 방식을 어떻게 바꾸었는지와 유사하게 React Server Component는 서버와 클라이언트를 활용하는 하이브리드 애플리케이션을 구축하기 위한 새로운 사고 모델을 소개합니다.

React는 전체 애플리케이션을 클라이언트 사이드 렌더링(SPA 같은)하는 대신 이제 목적에 따라 컴포넌트를 렌더링할 위치를 선택할 수 있는 유연성을 제공합니다.

예를 들어 다음과 같은 애플리케이션의 경우,

페이지를 더 작은 구성 요소로 분할하면 대부분의 구성 요소가 비대화형이며 서버 컴포넌트로 서버에서 렌더링될 수 있음을 알 수 있습니다.
작은 대화형 UI의 경우는 클라이언트 컴포넌트로 뿌릴 수 있습니다. 이것은 Next.js 서버 우선 접근 방식과 일치합니다.

서버 컴포넌트를 사용하는 이유

그렇다면 왜 서버 컴포넌트를 사용할까? 클라이언트 컴포넌트에 비해 서버 컴포넌트를 사용하면 어떤 이점이 있을까?

서버 컴포넌트를 통해 개발자는 서버 인프라를 더 잘 활용할 수 있습니다.
예를 들어, 데이터 페칭을 데이터베이스에 가까운 서버로 이전하고, 이전에는 서버의 클라이언트 JavaScript 번들 크기에 영향을 주었던 큰 종속성을 유지하여 성능을 향상시킬 수 있습니다.
서버 컴포넌트를 사용하면 React 애플리케이션을 작성하는 것이 PHP 또는 Ruby on Rails와 유사하게 느껴질 수 있지만, React의 강력함과 유연성 및 템플릿 UI용 컴포넌트 모델을 가지고 있습니다.

서버 컴포넌트를 사용하면 초기 페이지 로드가 더 빨라지고 클라이언트 사이드 JavaScript 번들 크기가 줄어듭니다. 기본 클라이언트 사이드 런타임은 캐시 가능하고 예측가능한 크기이며 애플리케이션이 커져도 늘어나지 않습니다. 추가적인 JavaScript는 클라이언트 컴포넌트를 통해 애플리케이션에서 클라이언트 측 상호 작용이 사용되는 경우에만 추가됩니다.

Next.js로 로드되면, 초기 HTML은 서버에서 렌더링 됩니다. 그런 다음 이 HTML은 브라우저에서 점진적으로 향상되어 클라이언트가 Next.js 및 React 클라이언트 사이드 런타임을 비동기적으로 로드하여 애플리케이션을 넘겨받고 상호작용을 추가할 수 있습니다.

서버 컴포넌트로 전환을 더 쉽게 하기 위해 앱 라우터 내부의 모든 구성 요소는 특수 파일(layout.tsx, page.tsx 등)공동 배치 컴포넌트(colocated component - app 디렉토리 내 특수 파일을 제외한 다른 파일들)를 포함하여 기본적으로 서버 구성 요소입니다.
이를 통해 추가 작업 없이 자동으로 서버 컴포넌트를 즉시 사용해 뛰어난 성능을 얻을 수 있습니다. 또한 'use client' 지시문을 사용하여 선택적으로 클라이언트 컴포넌트로 사용할 수 있습니다.


클라이언트 컴포넌트

클라이언트 구성 요소를 사용하면 애플리케이션에 클라이언트 측 상호 작용을 추가할 수 있습니다.
Next.js는 서버에서 미리 렌더링되고 클라이언트에서 수화(hydration)됩니다. 페이지 라우터의 구성 요소가 항상 작동하는 방식으로 클라이언트 구성 요소를 생각할 수 있습니다.

'use client' 지시문

'use client' 지시문은 서버와 클라이언트 컴포넌트 모듈 그래프 사이의 경계를 선언하는 규칙입니다.

'use client'
 
import { useState } from 'react'
 
export default function Counter() {
  const [count, setCount] = useState(0)
 
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

'use clinet' 지시문은 서버 전용 코드와 클라이언트 코드 사이에 위치합니다. 서버와 클라이언트 코드의 경계를 정의하기 위해 import 보다 위인 파일의 최상단에 위치합니다. 'use clinet' 지시문이 파일에 정의되면 자식 컴포넌트를 포함하여 import된 다른 모든 모듈은 클라이언트 번들의 일부로 간주됩니다.

서버 컴포넌트가 기본값이므로 "use client" 지시문으로 시작하는 모듈에서 정의하거나 가져오지 않는 한 모든 컴포넌트는 서버 컴포넌트 모듈 그래프의 일부입니다.

알아두면 좋은 정보:

  • 서버 구성 요소 모듈 그래프의 구성 요소는 서버에서만 렌더링되도록 보장됩니다.
  • 클라이언트 컴포넌트 모듈 그래프의 구성 요소는 주로 클라이언트에서 렌더링되지만 Next.js를 사용하면 서버에서 사전 렌더링되고 클라이언트에서 수화될 수도 있습니다.
  • 반드시 파일 최상단에 'use client'를 정의해야 합니다.
  • 'use clinet'는 모든 파일에서 정의할 필요가 없습니다. 클라이언트 모듈 경계는 진입점에서 한 번만 정의하면 클라이언트 컴포넌트로 간주되는 모든 모듈을 가져올 수 있습니다.

언제 서버 or 클라이언트 컴포넌트를 사용해야할까

클라이언트 컴포넌트를 사용해야 할 케이스가 없다면 app 디렉토리의 기본값인 서버 컴포넌트를 사용하는 것을 추천합니다.

다음 표에는 서버 및 클라이언트 컴포넌트의 다양한 사용 사례가 요약되어 있습니다.

요구 상황서버 컴포넌트클라이언트 컴포넌트
데이터 가져오기OX
백엔드 리소스 접근(직접)OX
민감한 정보 서버에서 보관(액세스 토큰, API key 등)OX
서버에 대한 큰 종속성 유지 / 클라이언트 측 JavaScript 줄이기OX
상호작용이나 이벤트 리스너 추가(onClick(), onChange() 등)XO
State나 LifeCycle Effect 사용(useState(), useReducer(), useEffect() 등)XO
브라우저 전용 API 사용XO
state, effect, 브라우저 API 기반 커스텀 훅 사용XO
React 클래스 컴포넌트 사용XO

사용 예

클라이언트 컴포넌트를 리프로 이동하기

애플리케이션의 성능을 향상시키기 위해 가능한 클라이언트 컴포넌트를 컴포넌트 트리의 리프로 이동하는 것이 좋습니다.

예를 들어 정적 요소(예: 로고, 링크 등)가 있는 레이아웃과 state를 사용하는 대화형 검색 표시줄이 있을 수 있습니다.

전체 레이아웃을 클라이언트 컴포넌트로 만드는 대신 상호작용 로직을 클라이언트 컴포넌트(예: <SearchBar />)로, 레이아웃을 서버 컴포넌트로 유지합니다. 즉, 레이아웃의 모든 컴포넌트의 Javascript를 클라이언트에 보낼 필요가 없음을 의미합니다.

// SearchBar is a Client Component
import SearchBar from './searchbar'
// Logo is a Server Component
import Logo from './logo'
 
// Layout is a Server Component by default
export default function Layout({ children }) {
  return (
    <>
      <nav>
        <Logo />
        <SearchBar />
      </nav>
      <main>{children}</main>
    </>
  )
}

서버 및 클라이언트 컴포넌트 조합하기

서버 및 클라이언트 컴포넌트는 동일한 컴포넌트 트리에서 결합될 수 있습니다.

React는 다음과 같이 렌더링을 처리합니다.
1. 서버에서 React는 클라이언트에 결과를 보내기 전에 모든 서버 컴포넌트를 렌더링합니다.

  • 여기에는 클라이언트 컴포넌트 내에 중첩된 서버 컴포넌트가 포함됩니다.
  • 이 단계에서 마주친 클라이언트 컴포넌트는 건너뜁니다.
  1. 클라이언트에서 React는 서버 컴포넌트의 렌더링된 결과에서 클라이언트 컴포넌트와 슬롯을 렌더링하여 서버와 클라이언트에서 수행된 작업을 병합합니다.
  • 서버 컴포넌트가 클라이언트 컴포넌트 내에 중첩된 경우 렌더링된 콘텐츠는 클라이언트 구성 요소 내에 올바르게 배치됩니다.

알아두면 좋은 정보: Next.js에서는 초기 페이지를 더 빠르게 로드하기 위해 초기 페이지 로드 중에 위 단계에서 서버 컴포넌트의 렌더링된 결과와 클라이언트 컴포넌트가 모두 서버에서 HTML로 미리 렌더링됩니다.

클라이언트 컴포넌트 내부에 중첩된 서버 컴포넌트

위에서 설명한 렌더링 흐름을 고려할 때 서버 컴포넌트를 클라이언트 컴포넌트에 import 하는데는 제한이 있습니다. 이 방식에는 추가적인 서버 왕복(round trip)이 필요하기 때문입니다.

지원되지 않는 패턴: 서버 컴포넌트를 클라이언트 컴포넌트에 import하기

다음 패턴은 지원되지 않습니다. 서버 컴포넌트를 클라이언트 컴포넌트로 import 할 수 없습니다.

'use client'
 
// This pattern will **not** work!
// You cannot import a Server Component into a Client Component.
import ExampleServerComponent from './example-server-component'
 
export default function ExampleClientComponent({ children }) {
  const [count, setCount] = useState(0)
 
  return (
    <>
      <button onClick={() => setCount(count + 1)}>{count}</button>
 
      <ExampleServerComponent />
    </>
  )
}

권장 패턴: 서버 컴포넌트를 Props로 클라이언트 컴포넌트에 전달

대신 클라이언트 컴포넌트를 디자인할 때 React Props을 사용하여 서버 컴포넌트의 "슬롯"을 표시할 수 있습니다.

서버 컴포넌트는 서버에서 렌더링되고 클라이언트 컴포넌트가 클라이언트에서 렌더링될 때 "슬롯"은 서버 컴포넌트의 렌더링된 결과로 채워집니다.

일반적인 패턴은 React children prop을 사용하여 "슬롯"을 만드는 것입니다.
<ExampleClientComponent>children prop을 받도록 하고 <ExampleClientComponent>의 import 및 명시적 중첩을 상위 컴포넌트로 이동합니다.

'use client'
 
import { useState } from 'react'
 
export default function ExampleClientComponent({ children }) {
  const [count, setCount] = useState(0)
 
  return (
    <>
      <button onClick={() => setCount(count + 1)}>{count}</button>
 
      {children}
    </>
  )
}

이제 <ExampleClientComponent>children에 무엇이 올지 알 수 없습니다. children이 서버 컴포넌트로 채워질 것이라는 사실을 모릅니다.

<ExampleClientComponent>의 책임은 children이 배치될 위치를 결정하는 것입니다.

부모 서버 컴포넌트에서는 <ExampleClientComponent><ExampleServerComponent> 두 가지를 모두 import 할 수 있습니다. 그리고 <ExampleServerComponent><ExampleClientComponent>children으로 넘겨줍니다.

// This pattern works:
// You can pass a Server Component as a child or prop of a
// Client Component.
import ExampleClientComponent from './example-client-component'
import ExampleServerComponent from './example-server-component'
 
// Pages in Next.js are Server Components by default
export default function Page() {
  return (
    <ExampleClientComponent>
      <ExampleServerComponent />
    </ExampleClientComponent>
  )
}

이 접근법을 사용하면 <ExampleClientComponent><ExampleServerComponent>의 렌더링이 분리되어 클라이언트 컴포넌트보다 먼저 서버에서 렌더링되는 서버 컴포넌트에 맞추어 독립적으로 렌더링될 수 있습니다.

알아두면 좋은 정보:

  • 이 패턴은 children prop이 있는 레이아웃 및 페이지에 이미 적용되어 있으므로 추가 래퍼 컴포넌트를 만들 필요가 없습니다.
  • React 컴포넌트(JSX)를 다른 컴포넌트로 전달하는 것은 새로운 개념이 아니며 항상 React 모델의 일부였습니다.
  • 이 방법은 prop을 받는 컴포넌트가 prop이 무엇인지 알지 못하기 때문에 서버 및 클라이언트 컴포넌트에서 작동합니다. 오직 전달받은 것을 어디에 두어야 하는지에 대해서만 책임이 있습니다.
    • 이렇게 하면 클라이언트 컴포넌트가 클라이언트에서 렌더링되기 훨씬 전에 서버에서 전달된 prop을 독립적으로 렌더링할 수 있습니다.
    • import된 child 컴포넌트를 다시 렌더링하는 부모 컴포넌트의 상태 변경을 방지하기 위해 콘텐츠 끌어 올리기와 동일한 전략이 사용되었습니다.
  • children prop뿐만 아니라 모든 prop을 사용하여 JSX를 넘겨줄 수 있습니다.

서버에서 클라이언트 컴포넌트로 props 전달(직렬화)

서버에서 클라이언트 컴포넌트로 전달되는 prop은 직렬화가 가능해야 합니다. 이는 함수, 날짜같은 값을 클라이언트 컴포넌트에 직접 전달할 수 없음을 의미합니다.

네트워크 경계(Network Boundary)는 어디 위치할까요?
앱 라우터에서 네트워크 경계는 서버 컴포넌트와 클라이언트 컴포넌트 사이에 위치합니다. 이는 getStaticProps/getServerSideProps와 페이지 컴포넌트 사이에 위치하는 페이지 라우터와의 차이점입니다. 서버 컴포넌트에 포함된 데이터 요청은 클라이언트 컴포넌트와 다르게 네트워크 경계를 넘지 않기 때문에 직렬화될 필요가 없습니다.

서버전용 코드를 클라이언트 컴포넌트에서 제외하기

JavaScript 모듈은 서버 및 클라이언트 컴포넌트간에 공유될 수 있으므로 서버에서만 실행되도록 의도된 코드가 클라이언트에 의도치 않게 포함될 수 있습니다.

예를 들어, 다음같은 데이터 페칭 함수에서:

export async function getData() {
  const res = await fetch('https://external-service.com/data', {
    headers: {
      authorization: process.env.API_KEY,
    },
  })
 
  return res.json()
}

getData()가 서버와 클라이언트에서 모두 동작할 것처럼 보이지만, 환경 변수 API_KEY에 접두사 NEXT_PUBLIC이 없기 때문에 서버에서만 접근할 수 있는 private 변수입니다. Next.js는 클라이언트 코드에서 private 변수는 빈 문자열로 대체하여 보안 정보 유출을 방지합니다.

결과적으로 getData()는 클라이언트에서 import와 export는 될 수 있지만 의도대로 동작하지 않을 것입니다. 그리고 환경 변수를 public으로 변경하면 동작은 하지만 민감한 정보가 유출됩니다.

따라서 이 함수는 서버에서만 실행하도록 의도하여 작성되었습니다.

"server only" 패키지

이러한 의도하지 않은 클라이언트에서 서버 코드 사용을 방지하기 위해 server-only 패키지를 사용하여 다른 개발자가 실수로 이러한 모듈 중 하나를 클라이언트 컴포넌트로 가져온 경우 빌드 타임 오류를 발생시킬 수 있습니다.

server-only 패키지를 사용하기 위해 먼저 설치합니다.

  • npm install server-only

그리고 서버 전용 코드가 포함된 모듈에 import 합니다.

import 'server-only'
 
export async function getData() {
  const res = await fetch('https://external-service.com/data', {
    headers: {
      authorization: process.env.API_KEY,
    },
  })
 
  return res.json()
}

이제 getData()를 import 하는 모든 클라이언트 컴포넌트는 이 모듈은 서버에서만 사용될 수 있습니다라는 빌드타임 에러를 수신합니다.

이에 상응하는 client-only 패키지는 클라이언트 전용 코드를 포함하는 모듈을 표시하는 데 사용할 수 있습니다. ex) window 객체에 접근하는 코드

데이터 페칭(Fetching)

클라이언트 컴포넌트에서 데이터를 페치할 수 있지만 클라이언트에서 데이터를 페칭해야 하는 특별한 이유가 없는 한 서버 컴포넌트에서 데이터를 페칭하는 것이 좋습니다. 데이터 페칭을 서버로 이동하면 성능과 사용자 경험이 향상됩니다.

서드파티 패키지

서버 컴포넌트가 새로운 개념이기 때문에 같은 생태계의 서드파티 패키지는 useState, useEffectcreateContext와 같은 클라이언트 전용 기능을 사용하는 컴포넌트에 "use client" 지시문을 추가하기 시작했습니다.

현재 클라이언트 전용 기능을 사용하는 npm 패키지의 많은 컴포넌트에는 아직 지시문이 없습니다. 이러한 서드파티 패키지는 "use client" 지시문이 있는 클라이언트 컴포넌트 내에서는 예상대로 작동하지만 서버 컴포넌트 내에서는 작동하지 않습니다.

예를 들어 <Carousel /> 컴포넌트를 가진 가상의 acme-carousel 패키지를 설치했다고 가정해 보겠습니다. 이 컴포넌트는 useState를 사용하지만 아직 "use client" 지시문이 없습니다.

클라이언트 컴포넌트에서 <Carousel />를 사용하면 예상한대로 동작합니다.

'use client'
 
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>
 
      {/*  Works, since Carousel is used within a Client Component */}
      {isOpen && <Carousel />}
    </div>
  )
}

그러나 서버 컴포넌트에서 직접 사용하려고 하면 에러가 발생합니다.

import { Carousel } from 'acme-carousel'
 
export default function Page() {
  return (
    <div>
      <p>View pictures</p>
 
      {/*  Error: `useState` can not be used within Server Components */}
      <Carousel />
    </div>
  )
}

그 이유는 Next.js가 <Carousel />가 클라이언트 전용 기능을 사용하고 있는 것을 알지 못하기 때문입니다.

이 문제를 해결하려면 클라이언트 컴포넌트에서 클라이언트 전용 기능에 의존하는 서드파티 컴포넌트를 래핑할 수 있습니다.

'use client'
 
import { Carousel } from 'acme-carousel'
 
export default Carousel

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

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

대부분의 서드파티 컴포넌트는 클라이언트 컴포넌트 내에서 사용할 가능성이 높으므로 래핑할 필요는 없습니다. 그러나 한 가지 예외가 있는데 공급자 컴포넌트(provider component)입니다. 이는 React statecontext에 의존하고 일반적으로 애플리케이션의 루트에 필요하기 때문입니다.

라이브러리 작성

  • 라이브러리 작성자는 "use client" 지시문을 사용하여 패키지의 클라이언트 진입점을 표시할 수 있습니다. 이를 통해 패키지를 래핑하지 않고도 패키지의 컴포넌트를 서버 컴포넌트로 직접 import 할 수 있습니다.
  • 가져온 모듈이 서버 컴포넌트 모듈 그래프의 일부가 되도록 트리에서 더 깊은"use client"을 사용하여 패키지를 최적화할 수 있습니다.
  • 일부 번들러가 "use client" 지식문을 제거할 수 있다는 점을 유의할 필요가 있습니다. React Wrap Balancer 및 Vercel Analytics repositories에서 "use client"를 포함하도록 esbuild를 구성하는 방법의 예를 찾을 수 있습니다.

Context

대부분의 React 애플리케이션은 컴포넌트간에 데이터를 공유하기 위해 context에 의존합니다. contextcreateContext를 통해 직접 사용하거나 서드파티 라이브러리의 Provider 컴포넌트를 통해 간접적으로 사용할 수 있습니다.

Next.js 13에서는 클라이언트 컴포넌트에서는 context를 완전히 지원하지만 서버 컴포넌트에서는 context를 생성하거나 사용할 수 없습니다. 서버 컴포넌트는 React state를 가지지 않고(상호작용 X), context는 일부 React state가 업데이트된 후 트리에서 컴포넌트를 다시 렌더링하는 데 주로 사용되기 때문입니다.

클라이언트 컴포넌트에서 Context 사용하기

클라이언트 컴포넌트에서는 모든 context API들이 완전히 지원됩니다.

'use client'
 
import { createContext, useContext, useState } from 'react'
 
const SidebarContext = createContext()
 
export function Sidebar() {
  const [isOpen, setIsOpen] = useState()
 
  return (
    <SidebarContext.Provider value={{ isOpen }}>
      <SidebarNav />
    </SidebarContext.Provider>
  )
}
 
function SidebarNav() {
  let { isOpen } = useContext(SidebarContext)
 
  return (
    <div>
      <p>Home</p>
 
      {isOpen && <Subnav />}
    </div>
  )
}

그러나 Context Provider는 주로 현재 테마와 같은 전역 문제를 공유하기 위해 애플리케이션의 루트 근처에서 렌더링됩니다. 서버 컴포넌트에서 컨텍스트가 지원되지 않기 때문에 애플리케이션의 루트에서 컨텍스트를 만들려고 하면 오류가 발생합니다.

import { createContext } from 'react'
 
//  createContext is not supported in Server Components
export const ThemeContext = createContext({})
 
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ThemeContext.Provider value="dark">
          {children}
        </ThemeContext.Provider>
      </body>
    </html>
  )
}

따라서, 클라이언트 컴포넌트 안에서 컨텍스트를 만들고 렌더링합니다.

'use client'
 
import { createContext } from 'react'
 
export const ThemeContext = createContext({})
 
export default function ThemeProvider({ children }) {
  return <ThemeContext.Provider value="dark">{children}</ThemeContext.Provider>
}

이제 서버 컴포넌트에서 Provider를 직접 렌더링 할 수 있습니다.

import ThemeProvider from './theme-provider'
 
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  )
}

Provider가 루트에서 렌더링되면 앱 전체의 다른 모든 클라이언트 컴포넌트가 이 컨텍스트를 사용할 수 있습니다.

서버 컴포넌트에서 서드파티 Context Provider 렌더링하기

"use client" 지시문이 없는 경우 서버 컴포넌트에서 바로 사용할 수 없기 때문에 클라이언트 컴포넌트로 매핑해서 사용(위 내용과 동일)

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

서버 컴포넌트는 대화형이 아니므로 React state를 사용하지 않으므로 데이터를 공유하기 위해 컨텍스트가 필요하지 않습니다. 대신 여러 서버 컴포넌트가 액세스해야 하는 공통 데이터에 대해 네이티브 JavaScript 패턴을 사용할 수 있습니다. 예를 들어 모듈을 사용하여 여러 컴포넌트에서 데이터베이스에 연결해 데이터를 공유할 수 있습니다.

/* utils/database.js */
export const db = new DatabaseConnection()
/* app/users/layout.js */
import { db } from '@utils/database'
 
export async function UsersLayout() {
  let users = await db.query()
  // ...
}
/* app/users/[id]/page.js */
import { db } from '@utils/database'
 
export async function DashboardPage() {
  let user = await db.query()
  // ...
}

위의 예에서 layoutpage 모두 데이터베이스 쿼리가 필요합니다. 각 컴포넌트는 @utils/database 모듈을 가져와서 데이터베이스에 대한 액세스를 공유합니다. 이 JavaScript 패턴을 글로벌 싱글톤이라고 합니다.

서버 컴포넌트간에 fetch 요청 공유하기

데이터를 fetch 할때, 그 결과를 page 또는 layout이나 자식 컴포넌트와 공유할 필요가 있을 수 있습니다. 이는 컴포넌트 간의 불필요한 연결이고, 컴포넌트 간 앞뒤로 props 전달을 하게 만듭니다.

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

원문 - https://nextjs.org/docs/getting-started/react-essentials

post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 8월 8일

좋은 정보 감사합니다

답글 달기