akjfal

Next13 공식문서 + 추가 설명 문서 본문

하루의 이슈

Next13 공식문서 + 추가 설명 문서

akjfal 2023. 6. 8. 11:57

작년에 신규 프로젝트를 하면서 Nextjs를 사용하던 중 Next 13이 출시되었었습니다. 이때 당시엔 정신이 없어서 살펴보지 못했는데 옆 팀 프로젝트 마감 기한이 너무 빡빡하게 잡혀서 2달 정도 도와주게 된 프로젝트에서 Next 13을 사용하고 있다고 합니다. 이번 기회에 공식 문서를 토대로 기존 방식과 달라진 점을 살펴보려고 합니다.

Next 13

New App Directory(Beta)

app directory는 현재 베타 버전이고, PR에는 추천하지 않습니다. 그리고 아직 pages directory는 next/image와 next/link 등 기존의 안정된 기능들과 함께 사용할 수 있습니다.

app directory는 아래 기능들은 지원합니다.

  • Layouts : state를 유지하고 리렌더링을 피하면서 경로들끼리 UI를 공유할 수 있습니다.
  • Server Copmponents : 가장 동적인 애플리케이션을 서버의 우선순위 기본값으로 설정합니다.
  • Streaming : 렌더링되는 UI 유닛 속에서 loading 상태와 흐름을 보여줍니다.
  • Support for Data Fetching : 비동기 서버 컴포넌트와 fetch API를 사용하면 컴포넌트 레벨을 가져올 수 잇습니다.

Layouts

app/을 통해서 navigation 전반에서 상태를 유지하고, 리렌더링을 방지하고, 고급 라우팅 패턴을 사용할 수 있습니다. 또한 레이아웃을 중첩 할 수 있고, 컴포넌트, 테스트 및 스타일과 같은 코드들을 어플리케이션 코드에 같은 곳에 배치할 수 있습니다.

우선 app/page.js를 만들어 봅시다.

export default function Page() {
  return (
    <h1>
      Hello, Next.js!
    </h1>
  )
}

이렇게 되었을 때 파일 시스템들에 layout들을 선언할 수 있습니다. 이러한 레이아웃들은 여러 페이지들이 공유할 수 있고, 리렌더링을 방지하는 등 여러 장점이 있습니다.

자세히 살펴 보면 아래와 같습니다. (생략한 항목들이 있으니, 시간이 되신다면 원문을 읽어보시길 추천합니다. 😊)

The app Directory

새로운 router 방식은 app으로 명명되었습니다. app directory는 pages directory가 남아있는 과정에서 실험적으로 채택되었습니다. 이 방식을 통해 일부 router를 새로운 방식으로 동작하도록 하고, 나머지는 이전 동작 방식을 유지할 수 있습니다.

※ 두 파일의 경로가 충돌할 경우 에러가 발생합니다.

기본적으로 app 은 React Server Components입니다. 이건 성능적으로 좋고, 쉽게 선택할 수 있지만, Client Components도 사용해야 합니다.

Folders and Files inside app

Folders : 폴더들은 경로를 규정하는데 사용됩니다. pages.js가 포함된 root 폴더에서 leaf폴더까지 계층 구조를 가지고, 이를 통해 single path를 만들어냅니다.

Files : routed속에서 UI를 만들어내는데 사용됩니다.

File Conventions

Nextjs에는 특별한 역할을 하는 파일들이 있습니다.

  • page.js : route에 특별한 UI를 만들 수 있고, public하게 접근할 수 있는 경로를 만듭니다.
    • route.js : 서버사이드 API의 엔드포인트를 만들 수 있습니다.
  • layout.js : segment와 자식들이 공유할 수 있는 UI를 만듭니다.
    • template.js : layout.js와 비슷하지만, 네비게이션에 새로운 컴포넌트 인스턴스가 마운트된 경우는 제외합니다. 이 경우를 빼면 layout.js를 사용하세요.
  • loading.js : segment와 children을 위한 loading UI를 만듭니다. Suspense Boundary속 페이지나 child segment로 감싸져 있으며, 해당 페이지들이 로드될 동안 로딩 UI를 노출시킵니다.
  • error.js : 로딩과 유사하게 error페이지를 띄워줍니다.
    • global-error.js : error.js와 비슷하지만, root의 layout.js의 에러를 잡습니다.
  • not-found.js : 알 수 없음 UI를 위한 것입니다.

Component Hierachy

위에서 살펴본 파일들의 계층 구조를 설명합니다.

이를 폴더들을 첨가한다면 아래와 같이 나타납니다.

Colocation

위에서 살펴본 파일들에더해서 추가로 여러 파일들을 폴더 속에 포함 시킬 수 있습니다. 예시로 styleshhets, tests, components등등이 있습니다.

Server-Centric Routing with Client-side Navigation

pages directory방식이 client-side routing을 사용하는 것과 달리, app directory방식은 Server Component와 서버에서 데이터 fetching을 통한 server-centric routing 방식을 사용합니다. server-centric-routing은 클라이언트가 경로 맵을 다운받을 필요가 없으며, 서버에서 해당 로직을 처리할 수 있습니다. 이러한 최적화는 많은 경로를 가진 프로그램일수록 더욱 좋습니다.

server-centric일지라도, 라우터는 client-side navigation을 Link컴포넌트와 함께 사용합니다. 이는 유저가 새로운 경로로 가도라도 브라우저가 페이지를 새로 로드할 필요가 없음을 의미합니다. 대신에 URL이 업데이트되면, Nextjs는 변화된 부분만 렌더링합니다.

추가적으로 라우터는 클라이언트 캐시에 서버 컴포넌트의 결과를 저장해둡니다. 이 캐시는 경로 세그먼트에 의해서 쪼개져서 모든 레벨에서 무효화를 허용하고, 렌더링 간에 일관성을 보장합니다. 따라서 이전에 가져온 세그먼트의 캐시를 사용해 성능을 더욱 향상 시킬 수 있습니다.

Partial Rendering

형제 경로 간 이동할 때 Nextjs는 레이아웃과 페이지를 변경된 부분만 불러냅니다. 이를 통해 중복 렌더링과 패치를 막을 수 있습니다.


Server Components

app directory는 React에서 새로나온 Server Components architecture를 지원합니다. Server and Client Components는 서버와 클라이언트에서 각자 최적의 상태로 작동합니다.

Server Components를 사용하게되어서, 클라이언트로 전송하는 자바스크립트의 코드량을 줄일 수 있게되었고, 따라서 페이지 로드가 빨라졌습니다.

경로가 로드 되면, Next.js와 React 런타임이 로드되는데 이는 캐시가 가능하고, 사이즈 예측이 가능합니다. 이 런타임은 프로젝트 크기가 커져도 변함이 없습니다. 또한 런타임은 비동기로 로드되고, 서버에 있던 HTML이 클라이언트에서 추가될 수 있습니다.

서버 컴포넌트에 대해서 자세한 이해를 위해서 Rendering Fundamentals를 먼저 이해해야 합니다.

Component-level Client and Server Rendering

React 18이전에 React의 모든 컴포넌트는 클라이언트에서 렌더링 되었습니다.

그래서 기존 Next.js에서는 페이지에서 쉽게 재구성할 수있는 방법을 제공했고, 서버에서 HTML을 프리렌더했고, 클라이언트에 리액트에 의해서 hydrate되도록 제공했습니다. 하지만 이 방법은 초기 HTML에서 추가적인 js 로직이 동작해야 합니다.

Server and Client Component덕분에 React는 서버와 클라이언트에서 선택적으로 렌더링이 가능합니다.

app directory는 서버 컴포넌트를 기본으로 사용하고, 클라이언트에 보내는 js의 양을 줄일 수 있습니다.

그리고 서버 컴포넌트 사이에 클라이언트 컴포넌트를 끼워넣을 수 있으며, 서버 컴포넌트가 클라이언트 컴포넌트의 자식처럼 사용할 수 도 있습니다.

아래 그림을 보면 이해가 쉽습니다.

Static and Dynamic Rendering on the Server

Next.js는 static과 dynamic rendring을 통해 렌더링 최적화 옵션을 제공합ㄴ디ㅏ.

Static Rendering

Static Rendering에서는 서버컴포넌트와 클라이언트 컴포넌트 모두 서버에서 빌드됩니다. 해당 빌드 파일은 클라이언트에서 캐싱되고, 재사용됩니다.

하지만 서버 컴포넌트와 클라이언트 컴포넌트 둘은 다른 방식으로 렌더링 됩니다.

  • 클라이언트 컴포넌트는 html과 json을 서버에 프리렌더링하여 캐싱합니다. 캐싱된 결과는 클라이언트에 하이드레이션하기 위해 전송됩니다.
  • 서버 컴포넌트는 React로 서버에서 렌더링되고, 해당 payload는 HTML 생성을 합니다. 이렇게 렌더링된 payload는 클라이언트의 컴포넌트에 하이드레이드하는데 사용되어서 클라이언트에서 JS가 필요하지 않습니다.

Dynamic Rendering

동적 렌더링은 서버와 클라이언트 컴포넌트 모두가 서버에서 렝더링되며 캐싱되지 않습니다.

Edge and Node.js Runtimes

서버에서 페이지를 렌더링하는것은 2가지 타입이 있습니다.

  • Node.js 런타임은 모든 Node.js 호환되는 것을 사용할 수 있습니다.
  • Edge 런타임은 웹 API를 기반으로 합니다.

서버 컴포넌트와 클라이언트 컴포넌트가 돌아가는 렌더링 방식에 대해서 알아 봤으니 서버 컴포넌트오 ㅏ클라이언트 컴포넌트에 대해서 알아봅시다.

Server Components

app directory의 모든 컴포넌트들은 서버컴포넌트와 부수적인 파일 및 컴포넌트들을 모두 가지고 있습니다. 이건 추가작업없이 바로 좋은 성능을 낼 수 있도록 합니다.

Why Server Components?

React Server componnets를 통해 개발자는 서버 인프라를 효율적으로 사용할 수 있습니다. 예를들어 클라이언트의 JS 번들 크기 중 큰 부분을 차지 했던 의존관계를 서버에 두어 성능이 향상 될 수 있습니다.

루트가 Next.js로 로드되면 초기 HTML이 서버에 렌더링 되고, 이후 비동기로 로드를해 추가적인 인터렉션을 구현합니다.

서버 컴포넌트 사용시 초기 로드가 빨라지고, 번들의 사이즈가 줄어듭니다.

Client components

클라이언트 컴포넌트느느 서버에서 프리렌더링되고 클라이언트에 하이드레이팅됩니다.

Convention

클라이언트 컴포넌트는 “use Client”를 사용합니다. 해당 컴포넌트는 어디에나 사용될 수 있고, app/에 있을 필요는 없습니다. 만약에 useState나 useEffect같은 hooks를 사용한다면 해당 마크를 남겨 놓을 필요가 있습니다.

When to use Server vs. Client Components?

아래 요약표가 있으니 참고하면 좋습니다.

원하는 동작 Server Client

데이터 fetch
백엔드 데이터에 직접 접근
민감정보 소유
서버에 의존도를 높여 번들사이즈 감소
onClick, onChange동작
life cycle 을 가진 hook사용
browser-only APIs
Class components

Importing Server Comp;onents into Client Components

서버컴포넌트와 클라이언트 컴포넌트는 같은 컴포넌트 트리로 만들 수 있지만, 서버 컴포넌트가 서버 전용 코드를 가질 수 있어 클라이언트 컴포넌트 내에 가져오는데는 제한이 있습니다.

따라서 이러한 패턴을 사용하기 위해서는 자식 요소로 넘겨야 합니다.

'use client'

export default function Clientcomponent({children}){
	return (
		<>
			{children}
		</>
	)
}

Passing props from Server to Client Components(Serialization)

서버 컴포넌트에서 클라이언트 컴포넌트로 props이 전달될 때는 시리얼화되어야 합니다. 즉 함수 등을 직접 전달할 수 없습니다.

Keeping SErver-Only code out of Client Components(Posioning)

js 모듈은 서버 컴포넌트와 클라이언트 컴포넌트가 공유하기 때문에, 서버에서만실행되도록 한 코드가 클라이언트에 들어갈 수 있습니다.

export asnyc function getData() {
	let res = await fetch('<https://example.com/data>', {
		headers: {
			authorization: process.env.API_KEY,
		}
	});
	return res.json();
}

위 코드에서 process.env.API_KEY가 있어서 해당 함수는 서버에서만 사용할 수 있습니다. 클라이언트에서 호출할 시 API_KEY가 없기 때문에 오류가 발생합니다.

이때 server-only 라이브러리를 사용하게 된다면, 해당 코드는 클라이언트에선 사용할 수 없음을 빌드에서 알려줍니다.

import 'server-only';

export asnyc function getData() {
	let res = await fetch('<https://example.com/data>', {
		headers: {
			authorization: process.env.API_KEY,
		}
	});
	return res.json();
}

이와 대응되는 ‘client-only’도 존재합니다.

Moving Client Components to the Leaves

성는ㅇ 향상을 위해서라면 클라이언트 컴포넌트를 leaf로 이동시키는 것이 좋습니다.

Third-party packages

“use client”는 새로 도입된 리액트 기능입니다. 그런데 아직 많은 라이브러리에선 해당 기능이 적용되지 않은 경우가 많아 서버 컴포넌트에서 사용하려고 할 때 에러가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 클라이언트 컴포넌트에서 따로 래핑해줘야합니다.

'use client'

// carousel.js
import { AcmeCarousel } from 'acme-carousel';

export default AcmeCarousel;
import Carousel from './carousel';

export default function Page() {
	return (
		<div>
			<p>View pictures</p>
			<Carousel />
		</div>
	);
}

Data Fetching

특별한 경우가 없다면 서버에서 데이터를 가져오길 권장하고 있습니다.

Context

대부분의 React 어플리에키션에선 context를 통해서 데이터를 전달하는데, Next.js의 서버 컴포넌트에선 이를 사용할 수 없습니다.

Using context in Client Components

클라이언트 컴포넌트에선 사용가능하기 때문에 이를 이용해야합니다. 컨텍스트 provider는 응용프로그램의 루트 근처에 렌더링 되기 때문에 클라이언트 컴포넌트에서 다로 래핑한 다음 사용해야 합니다.

'use client';

import { createContext } from 'react';

const ThemeContext = createContext();

export default function ThemeProvider({children}){
	return (
		<ThemeContext.Provider value="dark">
			{children}
		</ThemeContext.Provider>
	);
}

이렇게 클라이언트 컴포넌트에서 선언을 한ㄷ ㅏ음 ㅅ서버에서 사용해야합니다.

import ThemeProvider from './theme-provider';

exprot default function RootLayout({children}){
	return (
		<html>
			<body>
				<ThemeProvider>{children}</ThemeProvider>
			</body>
		</html>
	);
}

Sharing fetch requests between Server Components

페이지나 레이아웃 사이에서 fetch 데이터를 공유하기를 원할 수 도 있습니다. 이는 불필요한 결합들을 야기할 수 있습니다.

이럴 때 데이터를 사용하는 컴포넌트를 데이터오 ㅏ함께 가져오기를 권장합니다. 이럴 댄 어차피 캐시를 통해서 중복 요청은 배제되므로 훨 씬 효율적입니다.

Streaming

Next.js는 서버컴포넌트들과 퍼져있는 레이아웃들 덕분에 특정 데이터 없이 펠더링 할 수 있습니다. 또한 로딩상태나 데이터 페칭중인 페이지를 보여줄 수 있습니다. 따라서 유저는 전체 페이지로 렌더링 되기를 안 기다려도 됩니다.

Data Fetching

React는 최근 Promise를 다루는 새로운 방법을 제시했습니다.

native fetch Web API는 React 와 Next.js에서 강화되었습니다. 자동적으로 중복 fetch를 제거하고, fetch, cache, 재검증 데이터등을 컴포넌트레벨에서 제공합니다. 이것을 SSG, SSR, ISR에서 바로 사용할 수 있습니다.

이것들은 UI, 에러처리, 로딩처리를 손쉽게해줍니다.

Data Fetching Fundamentals

<aside> 💡 기존에 사용하던 getServerSideProps, getStaticProps, getIniotialProps같은 데이터 페칭 메소드들은 app directory 방식에서는 사용할 수 없습니다.

</aside>

The fetch() API

새로운 data fetching 시스템은 native fetch() 웹 API로 구현되었고, 서버 컴포넌트에선 async/await를 사용합니다.

  • React는 자동으로 request 중복 제거를 제공합니다.
  • Next.js는 fetch에 캐싱과 재전송 옵션을 제공합니다.

Fetching Data on the Server

가능한 데이터 fetching은 서버 컴포넌트에서 할 것을 권장합니다. 아래와 같은 장점이 있습니다.

  • DB 등에 바로 접근할 수있다.
  • 토큰 등의 보안이 더 강화된다.
  • 같은 환경에서 데이터를 fetch하고 렌더링합니다. 이건 클라이언트와 서버간 연결을 감소 시켜, 클라이언트의 메인스레드 효율이 더욱 좋아집니다.
  • 클라이언트에서 여러 개별요청을 날리는 것보다 하나를 round-trip돌리는 것이 더 효율적입니다.
  • client-server waterfall을 줄일 수 있습니다.
  • 지역에 따라 가까운 곳에 페칭을 날려서 성능을 향상 시킬 수 있습니다.

Component-level Data Fetching

layout, page, component들에서 데이터 페이차 가능합니다. 또한 Sreaming과 suspense와 호환됩니다.

<aside> 💡 데이터를 부모레이아웃과 자식간에 데이터가 오가는 것은 불가능합니다. 같은 경로에서 같은 데이터를 여러번 호출하더라도 필요한 컴포넌트에서 바로 데이터 페치하기를 권장합니다. 어차피 중복 요청들은 캐시되고 삭제됩니다.

</aside>

Parallel and Sequentail Data Fetching

컴포넌트안에서 데이터가 fetching될 때 2가지 데이터 페칭 패턴에대해서 알아야 한다. (Parallel 과 Sequential)

  • Parallel data fetching : 요청들은 시작되고 데이터를 받아오는것이 동시에 진행됩니다. 이는 클라이언트와 서버간 waterfall을 감소시키고 전체시간을 감소시킵니다.
  • Sequentail datafetching : 요청들은 다른 요청들이 끝나는 것에 의존합니다. 요처으이 결과가 이전 요청의 결과에 의존하고 있을 때 발생합니다. 하지만 로드가 오래걸리는 것 처럼 보일 수 있습니다.

Automatic fetch() Request Deduping

만약 여러 컴포넌트들에서 같은 API들을 호출하게ㅗ딜 경우, Next.js는 자동적으로 요청들을 캐싱하고 중복 호출을 방지합니다.

  • 서버에서 캐쉬는 렌더링 프로세스가 끝날 때까지 서버 리퀘스트의 라이프타임지송합니다.
    • 이러한 최적화는 Layouts, Pages, Server Components, generateMetadata, generateStaticParams에서 발생합니다.
    • 이러한 최적화는 static 렌더링에서 적용됩니다.
  • 클라이언트에선, 캐쉬는 모든 페이지들이 리로드되기전에 유지됩니다.

<aside> 💡 POST는 적용 안됩니다.

</aside>

<aside> 💡 fetch를 사용하지 않는다면, React는 cache function을 제공하는데 이를 이요해보세요.

</aside>

Static and Dynamic Data Fetches

  • Static Data의 경우에는 바귀지 않는 데이터입니다.
  • Dynamic Data는 바뀌는 데이터입니다.

Next.js는 자동적으로 static 을 fetch합니다. 이것은 데이터가 빌드 될때 fetch되면 캐싱되고 재사용되는 것을 의미합니다.

이건 2가지 이점이 있습니다.

  1. 리퀘스트수를 줄여 로드 시간을 최소화합니다.
  2. 데이터가 캐싱되서 성능이 향상됩니다.

하지만 항상 최신 데이터가 필요하다면, dynamic으로 캐싱없이 사용해야합니다.

Caching Data

캐싱은 로컬에 데이터를 저장하는 프로세스이기 대문에 리패치를할 이유가 없습니다. Next.js 의 캐시는 HTTP캐시로 글로벌적으로 배포됩니다. 이는 캐시가 자동적으로 스케일링되고, 개발자의 플랫폼에 의존해서 여러 지역을 걸쳐서 공유될 수 있습니다.

Next.js는 fetch 함수의 옵션을 통해 서버의 각 요청에 영구 캐싱을 설정할 수 있습니다. 컴포넌트레벨의 데이터페칭과함게 이건 너의 어플리케이션코드가 데이터가 사용되는 곳에서 캐싱할 수 있도록 해줍니다.

서버렌더링동안, Next.js는 fetch를 하는 동안 이미 데이터가 불러와진적 있는지 캐시를 확인합니다. 만약 내역이 있다면 캐시된 데이터가 반환되고, 아니라면 요청을 통해 데이터를 가져옵니다.

<aside> 💡 fetch를 사용할 수 없다면, React는 cache함수를 제공하니 이를 이요해보세요.

</aside>

Reavalidating Data

Revalidating은 캐시를 지우고 데이터를 최신화하는 과정입니다. 이는 데이터가 최신 데이터인것을 보증하는데 쓰입니다.

Next.js는 2가지 방법을 제공합니다.

  • Background : 특정시간마다
  • On-demand : 매번

Streaming and Suspense

Streaming과 suspense은 클라이언트에서 렌더링화면 등을 보여주는 리엑트의 특징입니다.

nested Layout과 함께, 필요한 데이터 없이 페이지를 렌더링할 수 있고, 로딩화면을 보여줄 수 있습니다. 이것은 사용성을 높여줍니다.

Data Fetching

<aside> 💡 React team에서 개발된 내용으로 해당 내용을 참고해주시길 바랍니다.

</aside>

<aside> 💡 안정된 버전이 아니며, 계속해서 업데이트가 반영될 예정입니다.

</aside>

React와 Next.js 13은 데이터를 관리하고 fetch하는데 새로운 방식을 소개합니다. 새로운 데이터 fetching 시스템은 app directory에서 작동하고, fetch Web API로 구성되어 있습니다.

fetch()는 promise로 리턴되는 fetch remote resource에 사용되는 WEB API입니다. React는 fetch를 발전시켜 자동적으로 중복 요청을 제거하고, next.js는 캐싱과 revalidating을 할 수 있는 추가 옵션을 제공합니다.

async/await in Server Components

React RFC의 목적과 함께, 서버 컴포넌트에서 async와 await를 사용할 수 있습니다.

// app/page.tsx
async function getData() {
	const res = await fetch('...');
	return res.json();
}

export default async function Page(){
	const data = await getData();

	return <div></div>;
}

<aside> 💡 async Server Component는 ‘Promise<Element>’ is not a valid JSX element 를 방생시킵니다. 해당 에러는 현재 작업중입니다. 임시적으로 작업하기 위해 컴포넌트 상단에 {/* @ts-expect-error Async Server Component */} 해당 옵션을 추가하세요.

</aside>

Server Component Functions

Next.js는 서버 컴포넌트에서 사용할 수 있는 2가지 함수를 제공합니다.

  • cookies()
  • headers()

use in Client Componnents

use 는 await와 유사한 함수입니다. use는 promise를 컴포넌트, hooks, Suspesne와 함께 사용하는 방법을 제공합니다.

Static Data Fetching

기본적으로 fetch는 데이터를 자동으로 가져오고 무제한으로 캐시합니다.

Revalidating Data

캐쉬된 데이터를 interval로 확ㅇ니하려면, next.revalidate옵션을 통해 시간을 설정할 수 있습니다.

Dynamic Data Fetching

모든 요청마다 데이터를 새로고침하려면 cache: ‘no-store’옵션을 사용하세요.

Data Fetching Patterns

Parallel Data Fetching

client-server의 waterfall를 최소화하기 위해서, 아래와 같은 패턴을 추천합니다.

//app/artist/[username]/page.jsx
import Albums from './albums';

async function getArtist(username) {
	const res = await fetch(`https://api.example.com/artist/${username}`);
	return res.json();
}

async function getArtistAlbums(username) {
	const res = await fetch(`https://api.example.com/artist/${username}/albums`);
	return res.json();
}

export default async function Page({ params: {username} }){
	// Initiate both requests in parallel
	const artistData = getArtist(username);
	albumsData = getArtistAlbums(username);

	//Wait for the promises to resolve
	const [artist, albums] = await Promise.all([artiestData, albumsData]);

	return (
		<>

{artist.name}

			
		
	);
}

Server Component에서 await를 호출하기 전에 fetch를 시착하게되면, 각 요청은 동시에 시작할 수 있습니다. 이를 통해 water fall들을 피할 수 있습니다.

두 요청을 동시에 시작해서 시간을 아낄 수 있지만, 모든것이 불러오기전까지 렌더링할 수 없습니다.

사용자 경험을 높이기 위해서, suspense boundary를 추가해 렌더링을 분할하고, 빨리 결과의 일부를 표시할 수 있습니다.

export default async function Page({ params: {username}}){
	// Initiate both requrests in parallel
	const artistData = getArtist(username);
	const albumData = getArtistAlbums(username);
	
	// Wait for the artist's promise to resolve first
	const artist = await artistData;
	
	return (
		<>
			<h1>{artist.name}</h1>
			{/* Send the artist information first and wrap albums in a suspense boundary */}
			<Suspense fallback={<div>Loading...</div>}>
				<Albums promise={albumData} />
			</Suspense>
		</>
	);
}

// Albums Component
async function Albums({ promise }) {
	// wait for the albums promise to resolve
	const albums = await promise;
	
	return (
		<ul>
			{albums.map((album) => (
				<li key={album.id}>{album.name}</li>
			))}
		</ul>
	);
}

Sequential Data Fetching

fetch data를 순서대로하기위해서, 컴포넌트에서 할수도 있고, await를 통해서 기다릴 수도 있습니다.

async function Playlists({ artistID }) {
	// Wait for the playlists
	const playlists = await getArtistPlaylists(artistID);
	
	return (
		<ul>
			{playlist.map((playlist) => (
				<li key={playlist.id}>{playlist.name}</li>
			))}
		</ul>
	);
}

export default async function Page({ params: { username } }) {
	// Wait for the artist
	const artist = await getArtist(username);
	
	return (
		<>
			<h1>{artist.name}</h1>
			<Suspnese fallback={<div>Loading...</div>}>
				<Playlists artistID={artist.id} />
			</Suspense>
		</>
	);
}

만약 컴포넌트안에서 fetching이 발생하게되면, 각 요청들을 이전 요청이 끝나기전까지 시작하지 못합니다.

Blocking Rendering in a Route

layout에서 fetch를 하게되며 ㄴ해당 동작이 끝나야만 아래 컴포넌트나 페이지들의 동작이 발생합니다.

pages directory에서는 page는 getServerSideProps가 내려올때까지 loading spinner를 발생시켰습니다. 이건 전부 혹은 없ㄴ느 방식입니다.

app directory에서는 추가적이 ㄴ옵션이 있습니다.

  1. 첫번째로 loading.js를 통해서 서버에서 결과데이터가 오기전까지 보여줄 수 있습니다.
  2. 두번째는 필요한 곳들만 막고 렌더링화면을 보여주는 방식이 있습니다.

무엇을 하든 가장 좋은반법은 부분적으로 하는 방식일 것입니다. 이건 부분적으로 로딩페이지만을 보여주어 사용성을 높일 수 있습니다.

Data Fetching without fetch()

third-party library를 사용한다면 매번 직접 다루어야할 필요없습니다.

fetch를 사용할수가 없지만, 여전히 캐신이나 revalidating을 사용하고 싶을 때 caching이나 caching확인을 사요하면 됩니다.

Default Caching Behavior

data fetching 라이브러리들은 라우크 캐싱에 잊ㄱ접 영햘을 키지지 않고, 경로에 따라 static이나 dynamic입니다.

만약 static일경우네는 캐싱되고 revalidated되지만, 동적일 경우 캐싱되지않고, 모든요청에 유효성검사를 합니다.

Segment Cache Configuration

서드파티 쿼리들이 확인되서 캐싱되기전까지, segment configuration을 임시로 사용할 수 있습니다.

// app/page.tsx
import prisma from './lib/prisma';

export const revalidate = 3600;

async function getPost() {
	const posts = await prisma.post.findMany();
	return posts;
}

export default async function Page(){
	const posts = await getPosts();
	...
}

Intorducing Turbopack(Alpha)

webpack의 후계자인 Turbopack을 통해서 많은 속도 향상이 일어났습니다.

next/image

새로운 이미지 컴포넌트를 출시했습니다.

  • client side 부하 감소
  • 스타일링 용이
  • 플랫폼에 맞게 조절
  • hydration 불필요

next/font

  • 자동 최적화
  • 외부 네트워크 요청을 제거하여 성능 향상
  • 자동 셀프 호스팅 기능
  • css size-adjust 속성을 통해 자동 이동

next/link

a를 더이상 자식에 넣을 필요가 없습니다.

OG Image Generation

오픈 그래프 이미지 생성을 Vercel을 통해서 소셜 카드 이미지를 만들수 있습니다.

  • Performance : 빠르게 만들 수 있습니다.
  • Ease of use : HTML과 CSS를 이용하여 할 수 있습니다.
  • Cost-effectiveness : 캐싱등을 통해 비용 절감이 가능합니다.

Middleware API Updates

12에도 미들웨어가 있었지만, 13에선 더욱 발전했습니다.

헤더에 값을 추가하는 예시입니다.

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
	const requestHeaders = new Headers(request.headers);
	requestHeaders.set('x-version', '13');

	const response = NextResponse.next({
		request: {
			headers: requestHeaders,
		},
	});

	response.headers.set('x-version', '13');
	return response;
}

Bearking Changes

  • 최소 React 버전이 17.0.2에서 18.2.0으로 올라갔습니다.
  • Node.js 최소 버전이 12.22.0dptj 14.6.0으로 올라갔습니다.
  • swcMinify옵션이 false에서 true로 기본값이 바뀌었습니다.
  • next/image의 import 경로가 바뀌었습니다.
  • next/link에 a태그를 더이상 추가할 필요 없습니다.
  • User-Agent가 bot일 때 더이상 경로를 prefetch하지 않습니다.
  • next.config.js의 target옵션이 사라졌습니다.
  • IE 지원이 종료되었고, 브라우저들 버전이 올라왔습니다.

    Next 13

    New App Directory(Beta)app directory는 아래 기능들은 지원합니다.
    • Layouts : state를 유지하고 리렌더링을 피하면서 경로들끼리 UI를 공유할 수 있습니다.
    • Server Copmponents : 가장 동적인 애플리케이션을 서버의 우선순위 기본값으로 설정합니다.
    • Streaming : 렌더링되는 UI 유닛 속에서 loading 상태와 흐름을 보여줍니다.
    • Support for Data Fetching : 비동기 서버 컴포넌트와 fetch API를 사용하면 컴포넌트 레벨을 가져올 수 잇습니다.
    Layouts우선 app/page.js를 만들어 봅시다.이렇게 되었을 때 파일 시스템들에 layout들을 선언할 수 있습니다. 이러한 레이아웃들은 여러 페이지들이 공유할 수 있고, 리렌더링을 방지하는 등 여러 장점이 있습니다.The app Directory※ 두 파일의 경로가 충돌할 경우 에러가 발생합니다.Folders and Files inside appFiles : routed속에서 UI를 만들어내는데 사용됩니다.Nextjs에는 특별한 역할을 하는 파일들이 있습니다.
    • page.js : route에 특별한 UI를 만들 수 있고, public하게 접근할 수 있는 경로를 만듭니다.
      • route.js : 서버사이드 API의 엔드포인트를 만들 수 있습니다.
    • layout.js : segment와 자식들이 공유할 수 있는 UI를 만듭니다.
      • template.js : layout.js와 비슷하지만, 네비게이션에 새로운 컴포넌트 인스턴스가 마운트된 경우는 제외합니다. 이 경우를 빼면 layout.js를 사용하세요.
    • loading.js : segment와 children을 위한 loading UI를 만듭니다. Suspense Boundary속 페이지나 child segment로 감싸져 있으며, 해당 페이지들이 로드될 동안 로딩 UI를 노출시킵니다.
    • error.js : 로딩과 유사하게 error페이지를 띄워줍니다.
      • global-error.js : error.js와 비슷하지만, root의 layout.js의 에러를 잡습니다.
    • not-found.js : 알 수 없음 UI를 위한 것입니다.
    Component HierachyColocationServer-Centric Routing with Client-side Navigationserver-centric일지라도, 라우터는 client-side navigation을 Link컴포넌트와 함께 사용합니다. 이는 유저가 새로운 경로로 가도라도 브라우저가 페이지를 새로 로드할 필요가 없음을 의미합니다. 대신에 URL이 업데이트되면, Nextjs는 변화된 부분만 렌더링합니다.Partial Rendering
    Server ComponentsServer Components를 사용하게되어서, 클라이언트로 전송하는 자바스크립트의 코드량을 줄일 수 있게되었고, 따라서 페이지 로드가 빨라졌습니다.서버 컴포넌트에 대해서 자세한 이해를 위해서 Rendering Fundamentals를 먼저 이해해야 합니다.React 18이전에 React의 모든 컴포넌트는 클라이언트에서 렌더링 되었습니다.Server and Client Component덕분에 React는 서버와 클라이언트에서 선택적으로 렌더링이 가능합니다.그리고 서버 컴포넌트 사이에 클라이언트 컴포넌트를 끼워넣을 수 있으며, 서버 컴포넌트가 클라이언트 컴포넌트의 자식처럼 사용할 수 도 있습니다.Static Rendering하지만 서버 컴포넌트와 클라이언트 컴포넌트 둘은 다른 방식으로 렌더링 됩니다.
    • 클라이언트 컴포넌트는 html과 json을 서버에 프리렌더링하여 캐싱합니다. 캐싱된 결과는 클라이언트에 하이드레이션하기 위해 전송됩니다.
    • 서버 컴포넌트는 React로 서버에서 렌더링되고, 해당 payload는 HTML 생성을 합니다. 이렇게 렌더링된 payload는 클라이언트의 컴포넌트에 하이드레이드하는데 사용되어서 클라이언트에서 JS가 필요하지 않습니다.
    Dynamic RenderingEdge and Node.js Runtimes
    • Node.js 런타임은 모든 Node.js 호환되는 것을 사용할 수 있습니다.
    • Edge 런타임은 웹 API를 기반으로 합니다.
    서버 컴포넌트와 클라이언트 컴포넌트가 돌아가는 렌더링 방식에 대해서 알아 봤으니 서버 컴포넌트오 ㅏ클라이언트 컴포넌트에 대해서 알아봅시다.app directory의 모든 컴포넌트들은 서버컴포넌트와 부수적인 파일 및 컴포넌트들을 모두 가지고 있습니다. 이건 추가작업없이 바로 좋은 성능을 낼 수 있도록 합니다.React Server componnets를 통해 개발자는 서버 인프라를 효율적으로 사용할 수 있습니다. 예를들어 클라이언트의 JS 번들 크기 중 큰 부분을 차지 했던 의존관계를 서버에 두어 성능이 향상 될 수 있습니다.서버 컴포넌트 사용시 초기 로드가 빨라지고, 번들의 사이즈가 줄어듭니다.클라이언트 컴포넌트느느 서버에서 프리렌더링되고 클라이언트에 하이드레이팅됩니다.클라이언트 컴포넌트는 “use Client”를 사용합니다. 해당 컴포넌트는 어디에나 사용될 수 있고, app/에 있을 필요는 없습니다. 만약에 useState나 useEffect같은 hooks를 사용한다면 해당 마크를 남겨 놓을 필요가 있습니다.아래 요약표가 있으니 참고하면 좋습니다.원하는 동작 Server Client
    데이터 fetch
    백엔드 데이터에 직접 접근
    민감정보 소유
    서버에 의존도를 높여 번들사이즈 감소
    onClick, onChange동작
    life cycle 을 가진 hook사용
    browser-only APIs
    Class components
    Importing Server Comp;onents into Client Components따라서 이러한 패턴을 사용하기 위해서는 자식 요소로 넘겨야 합니다.Passing props from Server to Client Components(Serialization)Keeping SErver-Only code out of Client Components(Posioning)
    export asnyc function getData() {
    	let res = await fetch('<https://example.com/data>', {
    		headers: {
    			authorization: process.env.API_KEY,
    		}
    	});
    	return res.json();
    }
    
    위 코드에서 process.env.API_KEY가 있어서 해당 함수는 서버에서만 사용할 수 있습니다. 클라이언트에서 호출할 시 API_KEY가 없기 때문에 오류가 발생합니다.
    import 'server-only';
    
    export asnyc function getData() {
    	let res = await fetch('<https://example.com/data>', {
    		headers: {
    			authorization: process.env.API_KEY,
    		}
    	});
    	return res.json();
    }
    
    이와 대응되는 ‘client-only’도 존재합니다.성는ㅇ 향상을 위해서라면 클라이언트 컴포넌트를 leaf로 이동시키는 것이 좋습니다.“use client”는 새로 도입된 리액트 기능입니다. 그런데 아직 많은 라이브러리에선 해당 기능이 적용되지 않은 경우가 많아 서버 컴포넌트에서 사용하려고 할 때 에러가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 클라이언트 컴포넌트에서 따로 래핑해줘야합니다.
    import Carousel from './carousel';
    
    export default function Page() {
    	return (
    		<div>
    			<p>View pictures</p>
    			<Carousel />
    		</div>
    	);
    }
    
    Data FetchingContextUsing context in Client Components
    'use client';
    
    import { createContext } from 'react';
    
    const ThemeContext = createContext();
    
    export default function ThemeProvider({children}){
    	return (
    		<ThemeContext.Provider value="dark">
    			{children}
    		</ThemeContext.Provider>
    	);
    }
    
    이렇게 클라이언트 컴포넌트에서 선언을 한ㄷ ㅏ음 ㅅ서버에서 사용해야합니다.Sharing fetch requests between Server Components이럴 때 데이터를 사용하는 컴포넌트를 데이터오 ㅏ함께 가져오기를 권장합니다. 이럴 댄 어차피 캐시를 통해서 중복 요청은 배제되므로 훨 씬 효율적입니다.Next.js는 서버컴포넌트들과 퍼져있는 레이아웃들 덕분에 특정 데이터 없이 펠더링 할 수 있습니다. 또한 로딩상태나 데이터 페칭중인 페이지를 보여줄 수 있습니다. 따라서 유저는 전체 페이지로 렌더링 되기를 안 기다려도 됩니다.React는 최근 Promise를 다루는 새로운 방법을 제시했습니다.이것들은 UI, 에러처리, 로딩처리를 손쉽게해줍니다.<aside> 💡 기존에 사용하던 getServerSideProps, getStaticProps, getIniotialProps같은 데이터 페칭 메소드들은 app directory 방식에서는 사용할 수 없습니다.The fetch() API
    • React는 자동으로 request 중복 제거를 제공합니다.
    • Next.js는 fetch에 캐싱과 재전송 옵션을 제공합니다.
    Fetching Data on the Server
    • DB 등에 바로 접근할 수있다.
    • 토큰 등의 보안이 더 강화된다.
    • 같은 환경에서 데이터를 fetch하고 렌더링합니다. 이건 클라이언트와 서버간 연결을 감소 시켜, 클라이언트의 메인스레드 효율이 더욱 좋아집니다.
    • 클라이언트에서 여러 개별요청을 날리는 것보다 하나를 round-trip돌리는 것이 더 효율적입니다.
    • client-server waterfall을 줄일 수 있습니다.
    • 지역에 따라 가까운 곳에 페칭을 날려서 성능을 향상 시킬 수 있습니다.
    Component-level Data Fetching<aside> 💡 데이터를 부모레이아웃과 자식간에 데이터가 오가는 것은 불가능합니다. 같은 경로에서 같은 데이터를 여러번 호출하더라도 필요한 컴포넌트에서 바로 데이터 페치하기를 권장합니다. 어차피 중복 요청들은 캐시되고 삭제됩니다.Parallel and Sequentail Data Fetching
    • Parallel data fetching : 요청들은 시작되고 데이터를 받아오는것이 동시에 진행됩니다. 이는 클라이언트와 서버간 waterfall을 감소시키고 전체시간을 감소시킵니다.
    • Sequentail datafetching : 요청들은 다른 요청들이 끝나는 것에 의존합니다. 요처으이 결과가 이전 요청의 결과에 의존하고 있을 때 발생합니다. 하지만 로드가 오래걸리는 것 처럼 보일 수 있습니다.
    Automatic fetch() Request Deduping
    • 서버에서 캐쉬는 렌더링 프로세스가 끝날 때까지 서버 리퀘스트의 라이프타임지송합니다.
      • 이러한 최적화는 Layouts, Pages, Server Components, generateMetadata, generateStaticParams에서 발생합니다.
      • 이러한 최적화는 static 렌더링에서 적용됩니다.
    • 클라이언트에선, 캐쉬는 모든 페이지들이 리로드되기전에 유지됩니다.
    <aside> 💡 POST는 적용 안됩니다.<aside> 💡 fetch를 사용하지 않는다면, React는 cache function을 제공하는데 이를 이요해보세요.Static and Dynamic Data Fetches
    • Static Data의 경우에는 바귀지 않는 데이터입니다.
    • Dynamic Data는 바뀌는 데이터입니다.
    Next.js는 자동적으로 static 을 fetch합니다. 이것은 데이터가 빌드 될때 fetch되면 캐싱되고 재사용되는 것을 의미합니다.
    1. 리퀘스트수를 줄여 로드 시간을 최소화합니다.
    2. 데이터가 캐싱되서 성능이 향상됩니다.
    하지만 항상 최신 데이터가 필요하다면, dynamic으로 캐싱없이 사용해야합니다.캐싱은 로컬에 데이터를 저장하는 프로세스이기 대문에 리패치를할 이유가 없습니다. Next.js 의 캐시는 HTTP캐시로 글로벌적으로 배포됩니다. 이는 캐시가 자동적으로 스케일링되고, 개발자의 플랫폼에 의존해서 여러 지역을 걸쳐서 공유될 수 있습니다.서버렌더링동안, Next.js는 fetch를 하는 동안 이미 데이터가 불러와진적 있는지 캐시를 확인합니다. 만약 내역이 있다면 캐시된 데이터가 반환되고, 아니라면 요청을 통해 데이터를 가져옵니다.</aside>Revalidating은 캐시를 지우고 데이터를 최신화하는 과정입니다. 이는 데이터가 최신 데이터인것을 보증하는데 쓰입니다.
    • Background : 특정시간마다
    • On-demand : 매번
    Streaming and Suspensenested Layout과 함께, 필요한 데이터 없이 페이지를 렌더링할 수 있고, 로딩화면을 보여줄 수 있습니다. 이것은 사용성을 높여줍니다.<aside> 💡 React team에서 개발된 내용으로 해당 내용을 참고해주시길 바랍니다.<aside> 💡 안정된 버전이 아니며, 계속해서 업데이트가 반영될 예정입니다.React와 Next.js 13은 데이터를 관리하고 fetch하는데 새로운 방식을 소개합니다. 새로운 데이터 fetching 시스템은 app directory에서 작동하고, fetch Web API로 구성되어 있습니다.async/await in Server Components
    // app/page.tsx
    async function getData() {
    	const res = await fetch('...');
    	return res.json();
    }
    
    export default async function Page(){
    	const data = await getData();
    
    	return <div></div>;
    }
    
    <aside> 💡 async Server Component는 ‘Promise<Element>’ is not a valid JSX element 를 방생시킵니다. 해당 에러는 현재 작업중입니다. 임시적으로 작업하기 위해 컴포넌트 상단에 {/* @ts-expect-error Async Server Component */} 해당 옵션을 추가하세요.Server Component Functions
    • cookies()
    • headers()
    use in Client ComponnentsStatic Data FetchingRevalidating DataDynamic Data FetchingData Fetching Patternsclient-server의 waterfall를 최소화하기 위해서, 아래와 같은 패턴을 추천합니다.Server Component에서 await를 호출하기 전에 fetch를 시착하게되면, 각 요청은 동시에 시작할 수 있습니다. 이를 통해 water fall들을 피할 수 있습니다.사용자 경험을 높이기 위해서, suspense boundary를 추가해 렌더링을 분할하고, 빨리 결과의 일부를 표시할 수 있습니다.Sequential Data Fetching
    async function Playlists({ artistID }) {
    	// Wait for the playlists
    	const playlists = await getArtistPlaylists(artistID);
    	
    	return (
    		<ul>
    			{playlist.map((playlist) => (
    				<li key={playlist.id}>{playlist.name}</li>
    			))}
    		</ul>
    	);
    }
    
    export default async function Page({ params: { username } }) {
    	// Wait for the artist
    	const artist = await getArtist(username);
    	
    	return (
    		<>
    			<h1>{artist.name}</h1>
    			<Suspnese fallback={<div>Loading...</div>}>
    				<Playlists artistID={artist.id} />
    			</Suspense>
    		</>
    	);
    }
    
    만약 컴포넌트안에서 fetching이 발생하게되면, 각 요청들을 이전 요청이 끝나기전까지 시작하지 못합니다.layout에서 fetch를 하게되며 ㄴ해당 동작이 끝나야만 아래 컴포넌트나 페이지들의 동작이 발생합니다.app directory에서는 추가적이 ㄴ옵션이 있습니다.
    1. 첫번째로 loading.js를 통해서 서버에서 결과데이터가 오기전까지 보여줄 수 있습니다.
    2. 두번째는 필요한 곳들만 막고 렌더링화면을 보여주는 방식이 있습니다.
    무엇을 하든 가장 좋은반법은 부분적으로 하는 방식일 것입니다. 이건 부분적으로 로딩페이지만을 보여주어 사용성을 높일 수 있습니다.third-party library를 사용한다면 매번 직접 다루어야할 필요없습니다.Default Caching Behavior만약 static일경우네는 캐싱되고 revalidated되지만, 동적일 경우 캐싱되지않고, 모든요청에 유효성검사를 합니다.서드파티 쿼리들이 확인되서 캐싱되기전까지, segment configuration을 임시로 사용할 수 있습니다.Intorducing Turbopack(Alpha)next/image
    • client side 부하 감소
    • 스타일링 용이
    • 플랫폼에 맞게 조절
    • hydration 불필요
    next/font
    • 자동 최적화
    • 외부 네트워크 요청을 제거하여 성능 향상
    • 자동 셀프 호스팅 기능
    • css size-adjust 속성을 통해 자동 이동
    next/linkOG Image Generation
    • Performance : 빠르게 만들 수 있습니다.
    • Ease of use : HTML과 CSS를 이용하여 할 수 있습니다.
    • Cost-effectiveness : 캐싱등을 통해 비용 절감이 가능합니다.
    Middleware API Updates헤더에 값을 추가하는 예시입니다.Bearking Changes
    • 최소 React 버전이 17.0.2에서 18.2.0으로 올라갔습니다.
    • Node.js 최소 버전이 12.22.0dptj 14.6.0으로 올라갔습니다.
    • swcMinify옵션이 false에서 true로 기본값이 바뀌었습니다.
    • next/image의 import 경로가 바뀌었습니다.
    • next/link에 a태그를 더이상 추가할 필요 없습니다.
    • User-Agent가 bot일 때 더이상 경로를 prefetch하지 않습니다.
    • next.config.js의 target옵션이 사라졌습니다.
    • IE 지원이 종료되었고, 브라우저들 버전이 올라왔습니다.

      Next 13

      New App Directory(Beta)app directory는 아래 기능들은 지원합니다.
      • Layouts : state를 유지하고 리렌더링을 피하면서 경로들끼리 UI를 공유할 수 있습니다.
      • Server Copmponents : 가장 동적인 애플리케이션을 서버의 우선순위 기본값으로 설정합니다.
      • Streaming : 렌더링되는 UI 유닛 속에서 loading 상태와 흐름을 보여줍니다.
      • Support for Data Fetching : 비동기 서버 컴포넌트와 fetch API를 사용하면 컴포넌트 레벨을 가져올 수 잇습니다.
      Layouts우선 app/page.js를 만들어 봅시다.이렇게 되었을 때 파일 시스템들에 layout들을 선언할 수 있습니다. 이러한 레이아웃들은 여러 페이지들이 공유할 수 있고, 리렌더링을 방지하는 등 여러 장점이 있습니다.The app Directory※ 두 파일의 경로가 충돌할 경우 에러가 발생합니다.Folders and Files inside appFiles : routed속에서 UI를 만들어내는데 사용됩니다.Nextjs에는 특별한 역할을 하는 파일들이 있습니다.
      • page.js : route에 특별한 UI를 만들 수 있고, public하게 접근할 수 있는 경로를 만듭니다.
        • route.js : 서버사이드 API의 엔드포인트를 만들 수 있습니다.
      • layout.js : segment와 자식들이 공유할 수 있는 UI를 만듭니다.
        • template.js : layout.js와 비슷하지만, 네비게이션에 새로운 컴포넌트 인스턴스가 마운트된 경우는 제외합니다. 이 경우를 빼면 layout.js를 사용하세요.
      • loading.js : segment와 children을 위한 loading UI를 만듭니다. Suspense Boundary속 페이지나 child segment로 감싸져 있으며, 해당 페이지들이 로드될 동안 로딩 UI를 노출시킵니다.
      • error.js : 로딩과 유사하게 error페이지를 띄워줍니다.
        • global-error.js : error.js와 비슷하지만, root의 layout.js의 에러를 잡습니다.
      • not-found.js : 알 수 없음 UI를 위한 것입니다.
      Component HierachyColocationServer-Centric Routing with Client-side Navigationserver-centric일지라도, 라우터는 client-side navigation을 Link컴포넌트와 함께 사용합니다. 이는 유저가 새로운 경로로 가도라도 브라우저가 페이지를 새로 로드할 필요가 없음을 의미합니다. 대신에 URL이 업데이트되면, Nextjs는 변화된 부분만 렌더링합니다.Partial Rendering
      Server ComponentsServer Components를 사용하게되어서, 클라이언트로 전송하는 자바스크립트의 코드량을 줄일 수 있게되었고, 따라서 페이지 로드가 빨라졌습니다.서버 컴포넌트에 대해서 자세한 이해를 위해서 Rendering Fundamentals를 먼저 이해해야 합니다.React 18이전에 React의 모든 컴포넌트는 클라이언트에서 렌더링 되었습니다.Server and Client Component덕분에 React는 서버와 클라이언트에서 선택적으로 렌더링이 가능합니다.그리고 서버 컴포넌트 사이에 클라이언트 컴포넌트를 끼워넣을 수 있으며, 서버 컴포넌트가 클라이언트 컴포넌트의 자식처럼 사용할 수 도 있습니다.Static Rendering하지만 서버 컴포넌트와 클라이언트 컴포넌트 둘은 다른 방식으로 렌더링 됩니다.
      • 클라이언트 컴포넌트는 html과 json을 서버에 프리렌더링하여 캐싱합니다. 캐싱된 결과는 클라이언트에 하이드레이션하기 위해 전송됩니다.
      • 서버 컴포넌트는 React로 서버에서 렌더링되고, 해당 payload는 HTML 생성을 합니다. 이렇게 렌더링된 payload는 클라이언트의 컴포넌트에 하이드레이드하는데 사용되어서 클라이언트에서 JS가 필요하지 않습니다.
      Dynamic RenderingEdge and Node.js Runtimes
      • Node.js 런타임은 모든 Node.js 호환되는 것을 사용할 수 있습니다.
      • Edge 런타임은 웹 API를 기반으로 합니다.
      서버 컴포넌트와 클라이언트 컴포넌트가 돌아가는 렌더링 방식에 대해서 알아 봤으니 서버 컴포넌트오 ㅏ클라이언트 컴포넌트에 대해서 알아봅시다.app directory의 모든 컴포넌트들은 서버컴포넌트와 부수적인 파일 및 컴포넌트들을 모두 가지고 있습니다. 이건 추가작업없이 바로 좋은 성능을 낼 수 있도록 합니다.React Server componnets를 통해 개발자는 서버 인프라를 효율적으로 사용할 수 있습니다. 예를들어 클라이언트의 JS 번들 크기 중 큰 부분을 차지 했던 의존관계를 서버에 두어 성능이 향상 될 수 있습니다.서버 컴포넌트 사용시 초기 로드가 빨라지고, 번들의 사이즈가 줄어듭니다.클라이언트 컴포넌트느느 서버에서 프리렌더링되고 클라이언트에 하이드레이팅됩니다.클라이언트 컴포넌트는 “use Client”를 사용합니다. 해당 컴포넌트는 어디에나 사용될 수 있고, app/에 있을 필요는 없습니다. 만약에 useState나 useEffect같은 hooks를 사용한다면 해당 마크를 남겨 놓을 필요가 있습니다.아래 요약표가 있으니 참고하면 좋습니다.원하는 동작 Server Client
      데이터 fetch
      백엔드 데이터에 직접 접근
      민감정보 소유
      서버에 의존도를 높여 번들사이즈 감소
      onClick, onChange동작
      life cycle 을 가진 hook사용
      browser-only APIs
      Class components
      Importing Server Comp;onents into Client Components따라서 이러한 패턴을 사용하기 위해서는 자식 요소로 넘겨야 합니다.Passing props from Server to Client Components(Serialization)Keeping SErver-Only code out of Client Components(Posioning)
      export asnyc function getData() {
      	let res = await fetch('<https://example.com/data>', {
      		headers: {
      			authorization: process.env.API_KEY,
      		}
      	});
      	return res.json();
      }
      
      위 코드에서 process.env.API_KEY가 있어서 해당 함수는 서버에서만 사용할 수 있습니다. 클라이언트에서 호출할 시 API_KEY가 없기 때문에 오류가 발생합니다.
      import 'server-only';
      
      export asnyc function getData() {
      	let res = await fetch('<https://example.com/data>', {
      		headers: {
      			authorization: process.env.API_KEY,
      		}
      	});
      	return res.json();
      }
      
      이와 대응되는 ‘client-only’도 존재합니다.성는ㅇ 향상을 위해서라면 클라이언트 컴포넌트를 leaf로 이동시키는 것이 좋습니다.“use client”는 새로 도입된 리액트 기능입니다. 그런데 아직 많은 라이브러리에선 해당 기능이 적용되지 않은 경우가 많아 서버 컴포넌트에서 사용하려고 할 때 에러가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 클라이언트 컴포넌트에서 따로 래핑해줘야합니다.
      import Carousel from './carousel';
      
      export default function Page() {
      	return (
      		<div>
      			<p>View pictures</p>
      			<Carousel />
      		</div>
      	);
      }
      
      Data FetchingContextUsing context in Client Components
      'use client';
      
      import { createContext } from 'react';
      
      const ThemeContext = createContext();
      
      export default function ThemeProvider({children}){
      	return (
      		<ThemeContext.Provider value="dark">
      			{children}
      		</ThemeContext.Provider>
      	);
      }
      
      이렇게 클라이언트 컴포넌트에서 선언을 한ㄷ ㅏ음 ㅅ서버에서 사용해야합니다.Sharing fetch requests between Server Components이럴 때 데이터를 사용하는 컴포넌트를 데이터오 ㅏ함께 가져오기를 권장합니다. 이럴 댄 어차피 캐시를 통해서 중복 요청은 배제되므로 훨 씬 효율적입니다.Next.js는 서버컴포넌트들과 퍼져있는 레이아웃들 덕분에 특정 데이터 없이 펠더링 할 수 있습니다. 또한 로딩상태나 데이터 페칭중인 페이지를 보여줄 수 있습니다. 따라서 유저는 전체 페이지로 렌더링 되기를 안 기다려도 됩니다.React는 최근 Promise를 다루는 새로운 방법을 제시했습니다.이것들은 UI, 에러처리, 로딩처리를 손쉽게해줍니다.<aside> 💡 기존에 사용하던 getServerSideProps, getStaticProps, getIniotialProps같은 데이터 페칭 메소드들은 app directory 방식에서는 사용할 수 없습니다.The fetch() API
      • React는 자동으로 request 중복 제거를 제공합니다.
      • Next.js는 fetch에 캐싱과 재전송 옵션을 제공합니다.
      Fetching Data on the Server
      • DB 등에 바로 접근할 수있다.
      • 토큰 등의 보안이 더 강화된다.
      • 같은 환경에서 데이터를 fetch하고 렌더링합니다. 이건 클라이언트와 서버간 연결을 감소 시켜, 클라이언트의 메인스레드 효율이 더욱 좋아집니다.
      • 클라이언트에서 여러 개별요청을 날리는 것보다 하나를 round-trip돌리는 것이 더 효율적입니다.
      • client-server waterfall을 줄일 수 있습니다.
      • 지역에 따라 가까운 곳에 페칭을 날려서 성능을 향상 시킬 수 있습니다.
      Component-level Data Fetching<aside> 💡 데이터를 부모레이아웃과 자식간에 데이터가 오가는 것은 불가능합니다. 같은 경로에서 같은 데이터를 여러번 호출하더라도 필요한 컴포넌트에서 바로 데이터 페치하기를 권장합니다. 어차피 중복 요청들은 캐시되고 삭제됩니다.Parallel and Sequentail Data Fetching
      • Parallel data fetching : 요청들은 시작되고 데이터를 받아오는것이 동시에 진행됩니다. 이는 클라이언트와 서버간 waterfall을 감소시키고 전체시간을 감소시킵니다.
      • Sequentail datafetching : 요청들은 다른 요청들이 끝나는 것에 의존합니다. 요처으이 결과가 이전 요청의 결과에 의존하고 있을 때 발생합니다. 하지만 로드가 오래걸리는 것 처럼 보일 수 있습니다.
      Automatic fetch() Request Deduping
      • 서버에서 캐쉬는 렌더링 프로세스가 끝날 때까지 서버 리퀘스트의 라이프타임지송합니다.
        • 이러한 최적화는 Layouts, Pages, Server Components, generateMetadata, generateStaticParams에서 발생합니다.
        • 이러한 최적화는 static 렌더링에서 적용됩니다.
      • 클라이언트에선, 캐쉬는 모든 페이지들이 리로드되기전에 유지됩니다.
      <aside> 💡 POST는 적용 안됩니다.<aside> 💡 fetch를 사용하지 않는다면, React는 cache function을 제공하는데 이를 이요해보세요.Static and Dynamic Data Fetches
      • Static Data의 경우에는 바귀지 않는 데이터입니다.
      • Dynamic Data는 바뀌는 데이터입니다.
      Next.js는 자동적으로 static 을 fetch합니다. 이것은 데이터가 빌드 될때 fetch되면 캐싱되고 재사용되는 것을 의미합니다.
      1. 리퀘스트수를 줄여 로드 시간을 최소화합니다.
      2. 데이터가 캐싱되서 성능이 향상됩니다.
      하지만 항상 최신 데이터가 필요하다면, dynamic으로 캐싱없이 사용해야합니다.캐싱은 로컬에 데이터를 저장하는 프로세스이기 대문에 리패치를할 이유가 없습니다. Next.js 의 캐시는 HTTP캐시로 글로벌적으로 배포됩니다. 이는 캐시가 자동적으로 스케일링되고, 개발자의 플랫폼에 의존해서 여러 지역을 걸쳐서 공유될 수 있습니다.서버렌더링동안, Next.js는 fetch를 하는 동안 이미 데이터가 불러와진적 있는지 캐시를 확인합니다. 만약 내역이 있다면 캐시된 데이터가 반환되고, 아니라면 요청을 통해 데이터를 가져옵니다.</aside>Revalidating은 캐시를 지우고 데이터를 최신화하는 과정입니다. 이는 데이터가 최신 데이터인것을 보증하는데 쓰입니다.
      • Background : 특정시간마다
      • On-demand : 매번
      Streaming and Suspensenested Layout과 함께, 필요한 데이터 없이 페이지를 렌더링할 수 있고, 로딩화면을 보여줄 수 있습니다. 이것은 사용성을 높여줍니다.<aside> 💡 React team에서 개발된 내용으로 해당 내용을 참고해주시길 바랍니다.<aside> 💡 안정된 버전이 아니며, 계속해서 업데이트가 반영될 예정입니다.React와 Next.js 13은 데이터를 관리하고 fetch하는데 새로운 방식을 소개합니다. 새로운 데이터 fetching 시스템은 app directory에서 작동하고, fetch Web API로 구성되어 있습니다.async/await in Server Components
      // app/page.tsx
      async function getData() {
      	const res = await fetch('...');
      	return res.json();
      }
      
      export default async function Page(){
      	const data = await getData();
      
      	return <div></div>;
      }
      
      <aside> 💡 async Server Component는 ‘Promise<Element>’ is not a valid JSX element 를 방생시킵니다. 해당 에러는 현재 작업중입니다. 임시적으로 작업하기 위해 컴포넌트 상단에 {/* @ts-expect-error Async Server Component */} 해당 옵션을 추가하세요.Server Component Functions
      • cookies()
      • headers()
      use in Client ComponnentsStatic Data FetchingRevalidating DataDynamic Data FetchingData Fetching Patternsclient-server의 waterfall를 최소화하기 위해서, 아래와 같은 패턴을 추천합니다.Server Component에서 await를 호출하기 전에 fetch를 시착하게되면, 각 요청은 동시에 시작할 수 있습니다. 이를 통해 water fall들을 피할 수 있습니다.사용자 경험을 높이기 위해서, suspense boundary를 추가해 렌더링을 분할하고, 빨리 결과의 일부를 표시할 수 있습니다.Sequential Data Fetching
      async function Playlists({ artistID }) {
      	// Wait for the playlists
      	const playlists = await getArtistPlaylists(artistID);
      	
      	return (
      		<ul>
      			{playlist.map((playlist) => (
      				<li key={playlist.id}>{playlist.name}</li>
      			))}
      		</ul>
      	);
      }
      
      export default async function Page({ params: { username } }) {
      	// Wait for the artist
      	const artist = await getArtist(username);
      	
      	return (
      		<>
      			<h1>{artist.name}</h1>
      			<Suspnese fallback={<div>Loading...</div>}>
      				<Playlists artistID={artist.id} />
      			</Suspense>
      		</>
      	);
      }
      
      만약 컴포넌트안에서 fetching이 발생하게되면, 각 요청들을 이전 요청이 끝나기전까지 시작하지 못합니다.layout에서 fetch를 하게되며 ㄴ해당 동작이 끝나야만 아래 컴포넌트나 페이지들의 동작이 발생합니다.app directory에서는 추가적이 ㄴ옵션이 있습니다.
      1. 첫번째로 loading.js를 통해서 서버에서 결과데이터가 오기전까지 보여줄 수 있습니다.
      2. 두번째는 필요한 곳들만 막고 렌더링화면을 보여주는 방식이 있습니다.
      무엇을 하든 가장 좋은반법은 부분적으로 하는 방식일 것입니다. 이건 부분적으로 로딩페이지만을 보여주어 사용성을 높일 수 있습니다.third-party library를 사용한다면 매번 직접 다루어야할 필요없습니다.Default Caching Behavior만약 static일경우네는 캐싱되고 revalidated되지만, 동적일 경우 캐싱되지않고, 모든요청에 유효성검사를 합니다.서드파티 쿼리들이 확인되서 캐싱되기전까지, segment configuration을 임시로 사용할 수 있습니다.Intorducing Turbopack(Alpha)next/image
      • client side 부하 감소
      • 스타일링 용이
      • 플랫폼에 맞게 조절
      • hydration 불필요
      next/font
      • 자동 최적화
      • 외부 네트워크 요청을 제거하여 성능 향상
      • 자동 셀프 호스팅 기능
      • css size-adjust 속성을 통해 자동 이동
      next/linkOG Image Generation
      • Performance : 빠르게 만들 수 있습니다.
      • Ease of use : HTML과 CSS를 이용하여 할 수 있습니다.
      • Cost-effectiveness : 캐싱등을 통해 비용 절감이 가능합니다.
      Middleware API Updates헤더에 값을 추가하는 예시입니다.Bearking Changes
      • 최소 React 버전이 17.0.2에서 18.2.0으로 올라갔습니다.
      • Node.js 최소 버전이 12.22.0dptj 14.6.0으로 올라갔습니다.
      • swcMinify옵션이 false에서 true로 기본값이 바뀌었습니다.
      • next/image의 import 경로가 바뀌었습니다.
      • next/link에 a태그를 더이상 추가할 필요 없습니다.
      • User-Agent가 bot일 때 더이상 경로를 prefetch하지 않습니다.
      • next.config.js의 target옵션이 사라졌습니다.
      • IE 지원이 종료되었고, 브라우저들 버전이 올라왔습니다.

        Next 13

        New App Directory(Beta)app directory는 아래 기능들은 지원합니다.
        • Layouts : state를 유지하고 리렌더링을 피하면서 경로들끼리 UI를 공유할 수 있습니다.
        • Server Copmponents : 가장 동적인 애플리케이션을 서버의 우선순위 기본값으로 설정합니다.
        • Streaming : 렌더링되는 UI 유닛 속에서 loading 상태와 흐름을 보여줍니다.
        • Support for Data Fetching : 비동기 서버 컴포넌트와 fetch API를 사용하면 컴포넌트 레벨을 가져올 수 잇습니다.
        Layouts우선 app/page.js를 만들어 봅시다.이렇게 되었을 때 파일 시스템들에 layout들을 선언할 수 있습니다. 이러한 레이아웃들은 여러 페이지들이 공유할 수 있고, 리렌더링을 방지하는 등 여러 장점이 있습니다.The app Directory※ 두 파일의 경로가 충돌할 경우 에러가 발생합니다.Folders and Files inside appFiles : routed속에서 UI를 만들어내는데 사용됩니다.Nextjs에는 특별한 역할을 하는 파일들이 있습니다.
        • page.js : route에 특별한 UI를 만들 수 있고, public하게 접근할 수 있는 경로를 만듭니다.
          • route.js : 서버사이드 API의 엔드포인트를 만들 수 있습니다.
        • layout.js : segment와 자식들이 공유할 수 있는 UI를 만듭니다.
          • template.js : layout.js와 비슷하지만, 네비게이션에 새로운 컴포넌트 인스턴스가 마운트된 경우는 제외합니다. 이 경우를 빼면 layout.js를 사용하세요.
        • loading.js : segment와 children을 위한 loading UI를 만듭니다. Suspense Boundary속 페이지나 child segment로 감싸져 있으며, 해당 페이지들이 로드될 동안 로딩 UI를 노출시킵니다.
        • error.js : 로딩과 유사하게 error페이지를 띄워줍니다.
          • global-error.js : error.js와 비슷하지만, root의 layout.js의 에러를 잡습니다.
        • not-found.js : 알 수 없음 UI를 위한 것입니다.
        Component HierachyColocationServer-Centric Routing with Client-side Navigationserver-centric일지라도, 라우터는 client-side navigation을 Link컴포넌트와 함께 사용합니다. 이는 유저가 새로운 경로로 가도라도 브라우저가 페이지를 새로 로드할 필요가 없음을 의미합니다. 대신에 URL이 업데이트되면, Nextjs는 변화된 부분만 렌더링합니다.Partial Rendering
        Server ComponentsServer Components를 사용하게되어서, 클라이언트로 전송하는 자바스크립트의 코드량을 줄일 수 있게되었고, 따라서 페이지 로드가 빨라졌습니다.서버 컴포넌트에 대해서 자세한 이해를 위해서 Rendering Fundamentals를 먼저 이해해야 합니다.React 18이전에 React의 모든 컴포넌트는 클라이언트에서 렌더링 되었습니다.Server and Client Component덕분에 React는 서버와 클라이언트에서 선택적으로 렌더링이 가능합니다.그리고 서버 컴포넌트 사이에 클라이언트 컴포넌트를 끼워넣을 수 있으며, 서버 컴포넌트가 클라이언트 컴포넌트의 자식처럼 사용할 수 도 있습니다.Static Rendering하지만 서버 컴포넌트와 클라이언트 컴포넌트 둘은 다른 방식으로 렌더링 됩니다.
        • 클라이언트 컴포넌트는 html과 json을 서버에 프리렌더링하여 캐싱합니다. 캐싱된 결과는 클라이언트에 하이드레이션하기 위해 전송됩니다.
        • 서버 컴포넌트는 React로 서버에서 렌더링되고, 해당 payload는 HTML 생성을 합니다. 이렇게 렌더링된 payload는 클라이언트의 컴포넌트에 하이드레이드하는데 사용되어서 클라이언트에서 JS가 필요하지 않습니다.
        Dynamic RenderingEdge and Node.js Runtimes
        • Node.js 런타임은 모든 Node.js 호환되는 것을 사용할 수 있습니다.
        • Edge 런타임은 웹 API를 기반으로 합니다.
        서버 컴포넌트와 클라이언트 컴포넌트가 돌아가는 렌더링 방식에 대해서 알아 봤으니 서버 컴포넌트오 ㅏ클라이언트 컴포넌트에 대해서 알아봅시다.app directory의 모든 컴포넌트들은 서버컴포넌트와 부수적인 파일 및 컴포넌트들을 모두 가지고 있습니다. 이건 추가작업없이 바로 좋은 성능을 낼 수 있도록 합니다.React Server componnets를 통해 개발자는 서버 인프라를 효율적으로 사용할 수 있습니다. 예를들어 클라이언트의 JS 번들 크기 중 큰 부분을 차지 했던 의존관계를 서버에 두어 성능이 향상 될 수 있습니다.서버 컴포넌트 사용시 초기 로드가 빨라지고, 번들의 사이즈가 줄어듭니다.클라이언트 컴포넌트느느 서버에서 프리렌더링되고 클라이언트에 하이드레이팅됩니다.클라이언트 컴포넌트는 “use Client”를 사용합니다. 해당 컴포넌트는 어디에나 사용될 수 있고, app/에 있을 필요는 없습니다. 만약에 useState나 useEffect같은 hooks를 사용한다면 해당 마크를 남겨 놓을 필요가 있습니다.아래 요약표가 있으니 참고하면 좋습니다.원하는 동작 Server Client
        데이터 fetch
        백엔드 데이터에 직접 접근
        민감정보 소유
        서버에 의존도를 높여 번들사이즈 감소
        onClick, onChange동작
        life cycle 을 가진 hook사용
        browser-only APIs
        Class components
        Importing Server Comp;onents into Client Components따라서 이러한 패턴을 사용하기 위해서는 자식 요소로 넘겨야 합니다.Passing props from Server to Client Components(Serialization)Keeping SErver-Only code out of Client Components(Posioning)
        export asnyc function getData() {
        	let res = await fetch('<https://example.com/data>', {
        		headers: {
        			authorization: process.env.API_KEY,
        		}
        	});
        	return res.json();
        }
        
        위 코드에서 process.env.API_KEY가 있어서 해당 함수는 서버에서만 사용할 수 있습니다. 클라이언트에서 호출할 시 API_KEY가 없기 때문에 오류가 발생합니다.
        import 'server-only';
        
        export asnyc function getData() {
        	let res = await fetch('<https://example.com/data>', {
        		headers: {
        			authorization: process.env.API_KEY,
        		}
        	});
        	return res.json();
        }
        
        이와 대응되는 ‘client-only’도 존재합니다.성는ㅇ 향상을 위해서라면 클라이언트 컴포넌트를 leaf로 이동시키는 것이 좋습니다.“use client”는 새로 도입된 리액트 기능입니다. 그런데 아직 많은 라이브러리에선 해당 기능이 적용되지 않은 경우가 많아 서버 컴포넌트에서 사용하려고 할 때 에러가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 클라이언트 컴포넌트에서 따로 래핑해줘야합니다.
        import Carousel from './carousel';
        
        export default function Page() {
        	return (
        		<div>
        			<p>View pictures</p>
        			<Carousel />
        		</div>
        	);
        }
        
        Data FetchingContextUsing context in Client Components
        'use client';
        
        import { createContext } from 'react';
        
        const ThemeContext = createContext();
        
        export default function ThemeProvider({children}){
        	return (
        		<ThemeContext.Provider value="dark">
        			{children}
        		</ThemeContext.Provider>
        	);
        }
        
        이렇게 클라이언트 컴포넌트에서 선언을 한ㄷ ㅏ음 ㅅ서버에서 사용해야합니다.Sharing fetch requests between Server Components이럴 때 데이터를 사용하는 컴포넌트를 데이터오 ㅏ함께 가져오기를 권장합니다. 이럴 댄 어차피 캐시를 통해서 중복 요청은 배제되므로 훨 씬 효율적입니다.Next.js는 서버컴포넌트들과 퍼져있는 레이아웃들 덕분에 특정 데이터 없이 펠더링 할 수 있습니다. 또한 로딩상태나 데이터 페칭중인 페이지를 보여줄 수 있습니다. 따라서 유저는 전체 페이지로 렌더링 되기를 안 기다려도 됩니다.React는 최근 Promise를 다루는 새로운 방법을 제시했습니다.이것들은 UI, 에러처리, 로딩처리를 손쉽게해줍니다.<aside> 💡 기존에 사용하던 getServerSideProps, getStaticProps, getIniotialProps같은 데이터 페칭 메소드들은 app directory 방식에서는 사용할 수 없습니다.The fetch() API
        • React는 자동으로 request 중복 제거를 제공합니다.
        • Next.js는 fetch에 캐싱과 재전송 옵션을 제공합니다.
        Fetching Data on the Server
        • DB 등에 바로 접근할 수있다.
        • 토큰 등의 보안이 더 강화된다.
        • 같은 환경에서 데이터를 fetch하고 렌더링합니다. 이건 클라이언트와 서버간 연결을 감소 시켜, 클라이언트의 메인스레드 효율이 더욱 좋아집니다.
        • 클라이언트에서 여러 개별요청을 날리는 것보다 하나를 round-trip돌리는 것이 더 효율적입니다.
        • client-server waterfall을 줄일 수 있습니다.
        • 지역에 따라 가까운 곳에 페칭을 날려서 성능을 향상 시킬 수 있습니다.
        Component-level Data Fetching<aside> 💡 데이터를 부모레이아웃과 자식간에 데이터가 오가는 것은 불가능합니다. 같은 경로에서 같은 데이터를 여러번 호출하더라도 필요한 컴포넌트에서 바로 데이터 페치하기를 권장합니다. 어차피 중복 요청들은 캐시되고 삭제됩니다.Parallel and Sequentail Data Fetching
        • Parallel data fetching : 요청들은 시작되고 데이터를 받아오는것이 동시에 진행됩니다. 이는 클라이언트와 서버간 waterfall을 감소시키고 전체시간을 감소시킵니다.
        • Sequentail datafetching : 요청들은 다른 요청들이 끝나는 것에 의존합니다. 요처으이 결과가 이전 요청의 결과에 의존하고 있을 때 발생합니다. 하지만 로드가 오래걸리는 것 처럼 보일 수 있습니다.
        Automatic fetch() Request Deduping
        • 서버에서 캐쉬는 렌더링 프로세스가 끝날 때까지 서버 리퀘스트의 라이프타임지송합니다.
          • 이러한 최적화는 Layouts, Pages, Server Components, generateMetadata, generateStaticParams에서 발생합니다.
          • 이러한 최적화는 static 렌더링에서 적용됩니다.
        • 클라이언트에선, 캐쉬는 모든 페이지들이 리로드되기전에 유지됩니다.
        <aside> 💡 POST는 적용 안됩니다.<aside> 💡 fetch를 사용하지 않는다면, React는 cache function을 제공하는데 이를 이요해보세요.Static and Dynamic Data Fetches
        • Static Data의 경우에는 바귀지 않는 데이터입니다.
        • Dynamic Data는 바뀌는 데이터입니다.
        Next.js는 자동적으로 static 을 fetch합니다. 이것은 데이터가 빌드 될때 fetch되면 캐싱되고 재사용되는 것을 의미합니다.
        1. 리퀘스트수를 줄여 로드 시간을 최소화합니다.
        2. 데이터가 캐싱되서 성능이 향상됩니다.
        하지만 항상 최신 데이터가 필요하다면, dynamic으로 캐싱없이 사용해야합니다.캐싱은 로컬에 데이터를 저장하는 프로세스이기 대문에 리패치를할 이유가 없습니다. Next.js 의 캐시는 HTTP캐시로 글로벌적으로 배포됩니다. 이는 캐시가 자동적으로 스케일링되고, 개발자의 플랫폼에 의존해서 여러 지역을 걸쳐서 공유될 수 있습니다.서버렌더링동안, Next.js는 fetch를 하는 동안 이미 데이터가 불러와진적 있는지 캐시를 확인합니다. 만약 내역이 있다면 캐시된 데이터가 반환되고, 아니라면 요청을 통해 데이터를 가져옵니다.</aside>Revalidating은 캐시를 지우고 데이터를 최신화하는 과정입니다. 이는 데이터가 최신 데이터인것을 보증하는데 쓰입니다.
        • Background : 특정시간마다
        • On-demand : 매번
        Streaming and Suspensenested Layout과 함께, 필요한 데이터 없이 페이지를 렌더링할 수 있고, 로딩화면을 보여줄 수 있습니다. 이것은 사용성을 높여줍니다.<aside> 💡 React team에서 개발된 내용으로 해당 내용을 참고해주시길 바랍니다.<aside> 💡 안정된 버전이 아니며, 계속해서 업데이트가 반영될 예정입니다.React와 Next.js 13은 데이터를 관리하고 fetch하는데 새로운 방식을 소개합니다. 새로운 데이터 fetching 시스템은 app directory에서 작동하고, fetch Web API로 구성되어 있습니다.async/await in Server Components
        // app/page.tsx
        async function getData() {
        	const res = await fetch('...');
        	return res.json();
        }
        
        export default async function Page(){
        	const data = await getData();
        
        	return <div></div>;
        }
        
        <aside> 💡 async Server Component는 ‘Promise<Element>’ is not a valid JSX element 를 방생시킵니다. 해당 에러는 현재 작업중입니다. 임시적으로 작업하기 위해 컴포넌트 상단에 {/* @ts-expect-error Async Server Component */} 해당 옵션을 추가하세요.Server Component Functions
        • cookies()
        • headers()
        use in Client ComponnentsStatic Data FetchingRevalidating DataDynamic Data FetchingData Fetching Patternsclient-server의 waterfall를 최소화하기 위해서, 아래와 같은 패턴을 추천합니다.Server Component에서 await를 호출하기 전에 fetch를 시착하게되면, 각 요청은 동시에 시작할 수 있습니다. 이를 통해 water fall들을 피할 수 있습니다.사용자 경험을 높이기 위해서, suspense boundary를 추가해 렌더링을 분할하고, 빨리 결과의 일부를 표시할 수 있습니다.Sequential Data Fetching
        async function Playlists({ artistID }) {
        	// Wait for the playlists
        	const playlists = await getArtistPlaylists(artistID);
        	
        	return (
        		<ul>
        			{playlist.map((playlist) => (
        				<li key={playlist.id}>{playlist.name}</li>
        			))}
        		</ul>
        	);
        }
        
        export default async function Page({ params: { username } }) {
        	// Wait for the artist
        	const artist = await getArtist(username);
        	
        	return (
        		<>
        			<h1>{artist.name}</h1>
        			<Suspnese fallback={<div>Loading...</div>}>
        				<Playlists artistID={artist.id} />
        			</Suspense>
        		</>
        	);
        }
        
        만약 컴포넌트안에서 fetching이 발생하게되면, 각 요청들을 이전 요청이 끝나기전까지 시작하지 못합니다.layout에서 fetch를 하게되며 ㄴ해당 동작이 끝나야만 아래 컴포넌트나 페이지들의 동작이 발생합니다.app directory에서는 추가적이 ㄴ옵션이 있습니다.
        1. 첫번째로 loading.js를 통해서 서버에서 결과데이터가 오기전까지 보여줄 수 있습니다.
        2. 두번째는 필요한 곳들만 막고 렌더링화면을 보여주는 방식이 있습니다.
        무엇을 하든 가장 좋은반법은 부분적으로 하는 방식일 것입니다. 이건 부분적으로 로딩페이지만을 보여주어 사용성을 높일 수 있습니다.third-party library를 사용한다면 매번 직접 다루어야할 필요없습니다.Default Caching Behavior만약 static일경우네는 캐싱되고 revalidated되지만, 동적일 경우 캐싱되지않고, 모든요청에 유효성검사를 합니다.서드파티 쿼리들이 확인되서 캐싱되기전까지, segment configuration을 임시로 사용할 수 있습니다.Intorducing Turbopack(Alpha)next/image
        • client side 부하 감소
        • 스타일링 용이
        • 플랫폼에 맞게 조절
        • hydration 불필요
        next/font
        • 자동 최적화
        • 외부 네트워크 요청을 제거하여 성능 향상
        • 자동 셀프 호스팅 기능
        • css size-adjust 속성을 통해 자동 이동
        next/linkOG Image Generation
        • Performance : 빠르게 만들 수 있습니다.
        • Ease of use : HTML과 CSS를 이용하여 할 수 있습니다.
        • Cost-effectiveness : 캐싱등을 통해 비용 절감이 가능합니다.
        Middleware API Updates헤더에 값을 추가하는 예시입니다.Bearking Changes
        • 최소 React 버전이 17.0.2에서 18.2.0으로 올라갔습니다.
        • Node.js 최소 버전이 12.22.0dptj 14.6.0으로 올라갔습니다.
        • swcMinify옵션이 false에서 true로 기본값이 바뀌었습니다.
        • next/image의 import 경로가 바뀌었습니다.
        • next/link에 a태그를 더이상 추가할 필요 없습니다.
        • User-Agent가 bot일 때 더이상 경로를 prefetch하지 않습니다.
        • next.config.js의 target옵션이 사라졌습니다.
        • IE 지원이 종료되었고, 브라우저들 버전이 올라왔습니다.

          Next 13

          New App Directory(Beta)app directory는 아래 기능들은 지원합니다.
          • Layouts : state를 유지하고 리렌더링을 피하면서 경로들끼리 UI를 공유할 수 있습니다.
          • Server Copmponents : 가장 동적인 애플리케이션을 서버의 우선순위 기본값으로 설정합니다.
          • Streaming : 렌더링되는 UI 유닛 속에서 loading 상태와 흐름을 보여줍니다.
          • Support for Data Fetching : 비동기 서버 컴포넌트와 fetch API를 사용하면 컴포넌트 레벨을 가져올 수 잇습니다.
          Layouts우선 app/page.js를 만들어 봅시다.이렇게 되었을 때 파일 시스템들에 layout들을 선언할 수 있습니다. 이러한 레이아웃들은 여러 페이지들이 공유할 수 있고, 리렌더링을 방지하는 등 여러 장점이 있습니다.The app Directory※ 두 파일의 경로가 충돌할 경우 에러가 발생합니다.Folders and Files inside appFiles : routed속에서 UI를 만들어내는데 사용됩니다.Nextjs에는 특별한 역할을 하는 파일들이 있습니다.
          • page.js : route에 특별한 UI를 만들 수 있고, public하게 접근할 수 있는 경로를 만듭니다.
            • route.js : 서버사이드 API의 엔드포인트를 만들 수 있습니다.
          • layout.js : segment와 자식들이 공유할 수 있는 UI를 만듭니다.
            • template.js : layout.js와 비슷하지만, 네비게이션에 새로운 컴포넌트 인스턴스가 마운트된 경우는 제외합니다. 이 경우를 빼면 layout.js를 사용하세요.
          • loading.js : segment와 children을 위한 loading UI를 만듭니다. Suspense Boundary속 페이지나 child segment로 감싸져 있으며, 해당 페이지들이 로드될 동안 로딩 UI를 노출시킵니다.
          • error.js : 로딩과 유사하게 error페이지를 띄워줍니다.
            • global-error.js : error.js와 비슷하지만, root의 layout.js의 에러를 잡습니다.
          • not-found.js : 알 수 없음 UI를 위한 것입니다.
          Component HierachyColocationServer-Centric Routing with Client-side Navigationserver-centric일지라도, 라우터는 client-side navigation을 Link컴포넌트와 함께 사용합니다. 이는 유저가 새로운 경로로 가도라도 브라우저가 페이지를 새로 로드할 필요가 없음을 의미합니다. 대신에 URL이 업데이트되면, Nextjs는 변화된 부분만 렌더링합니다.Partial Rendering
          Server ComponentsServer Components를 사용하게되어서, 클라이언트로 전송하는 자바스크립트의 코드량을 줄일 수 있게되었고, 따라서 페이지 로드가 빨라졌습니다.서버 컴포넌트에 대해서 자세한 이해를 위해서 Rendering Fundamentals를 먼저 이해해야 합니다.React 18이전에 React의 모든 컴포넌트는 클라이언트에서 렌더링 되었습니다.Server and Client Component덕분에 React는 서버와 클라이언트에서 선택적으로 렌더링이 가능합니다.그리고 서버 컴포넌트 사이에 클라이언트 컴포넌트를 끼워넣을 수 있으며, 서버 컴포넌트가 클라이언트 컴포넌트의 자식처럼 사용할 수 도 있습니다.Static Rendering하지만 서버 컴포넌트와 클라이언트 컴포넌트 둘은 다른 방식으로 렌더링 됩니다.
          • 클라이언트 컴포넌트는 html과 json을 서버에 프리렌더링하여 캐싱합니다. 캐싱된 결과는 클라이언트에 하이드레이션하기 위해 전송됩니다.
          • 서버 컴포넌트는 React로 서버에서 렌더링되고, 해당 payload는 HTML 생성을 합니다. 이렇게 렌더링된 payload는 클라이언트의 컴포넌트에 하이드레이드하는데 사용되어서 클라이언트에서 JS가 필요하지 않습니다.
          Dynamic RenderingEdge and Node.js Runtimes
          • Node.js 런타임은 모든 Node.js 호환되는 것을 사용할 수 있습니다.
          • Edge 런타임은 웹 API를 기반으로 합니다.
          서버 컴포넌트와 클라이언트 컴포넌트가 돌아가는 렌더링 방식에 대해서 알아 봤으니 서버 컴포넌트오 ㅏ클라이언트 컴포넌트에 대해서 알아봅시다.app directory의 모든 컴포넌트들은 서버컴포넌트와 부수적인 파일 및 컴포넌트들을 모두 가지고 있습니다. 이건 추가작업없이 바로 좋은 성능을 낼 수 있도록 합니다.React Server componnets를 통해 개발자는 서버 인프라를 효율적으로 사용할 수 있습니다. 예를들어 클라이언트의 JS 번들 크기 중 큰 부분을 차지 했던 의존관계를 서버에 두어 성능이 향상 될 수 있습니다.서버 컴포넌트 사용시 초기 로드가 빨라지고, 번들의 사이즈가 줄어듭니다.클라이언트 컴포넌트느느 서버에서 프리렌더링되고 클라이언트에 하이드레이팅됩니다.클라이언트 컴포넌트는 “use Client”를 사용합니다. 해당 컴포넌트는 어디에나 사용될 수 있고, app/에 있을 필요는 없습니다. 만약에 useState나 useEffect같은 hooks를 사용한다면 해당 마크를 남겨 놓을 필요가 있습니다.아래 요약표가 있으니 참고하면 좋습니다.원하는 동작 Server Client
          데이터 fetch
          백엔드 데이터에 직접 접근
          민감정보 소유
          서버에 의존도를 높여 번들사이즈 감소
          onClick, onChange동작
          life cycle 을 가진 hook사용
          browser-only APIs
          Class components
          Importing Server Comp;onents into Client Components따라서 이러한 패턴을 사용하기 위해서는 자식 요소로 넘겨야 합니다.Passing props from Server to Client Components(Serialization)Keeping SErver-Only code out of Client Components(Posioning)
          export asnyc function getData() {
          	let res = await fetch('<https://example.com/data>', {
          		headers: {
          			authorization: process.env.API_KEY,
          		}
          	});
          	return res.json();
          }
          
          위 코드에서 process.env.API_KEY가 있어서 해당 함수는 서버에서만 사용할 수 있습니다. 클라이언트에서 호출할 시 API_KEY가 없기 때문에 오류가 발생합니다.
          import 'server-only';
          
          export asnyc function getData() {
          	let res = await fetch('<https://example.com/data>', {
          		headers: {
          			authorization: process.env.API_KEY,
          		}
          	});
          	return res.json();
          }
          
          이와 대응되는 ‘client-only’도 존재합니다.성는ㅇ 향상을 위해서라면 클라이언트 컴포넌트를 leaf로 이동시키는 것이 좋습니다.“use client”는 새로 도입된 리액트 기능입니다. 그런데 아직 많은 라이브러리에선 해당 기능이 적용되지 않은 경우가 많아 서버 컴포넌트에서 사용하려고 할 때 에러가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 클라이언트 컴포넌트에서 따로 래핑해줘야합니다.
          import Carousel from './carousel';
          
          export default function Page() {
          	return (
          		<div>
          			<p>View pictures</p>
          			<Carousel />
          		</div>
          	);
          }
          
          Data FetchingContextUsing context in Client Components
          'use client';
          
          import { createContext } from 'react';
          
          const ThemeContext = createContext();
          
          export default function ThemeProvider({children}){
          	return (
          		<ThemeContext.Provider value="dark">
          			{children}
          		</ThemeContext.Provider>
          	);
          }
          
          이렇게 클라이언트 컴포넌트에서 선언을 한ㄷ ㅏ음 ㅅ서버에서 사용해야합니다.Sharing fetch requests between Server Components이럴 때 데이터를 사용하는 컴포넌트를 데이터오 ㅏ함께 가져오기를 권장합니다. 이럴 댄 어차피 캐시를 통해서 중복 요청은 배제되므로 훨 씬 효율적입니다.Next.js는 서버컴포넌트들과 퍼져있는 레이아웃들 덕분에 특정 데이터 없이 펠더링 할 수 있습니다. 또한 로딩상태나 데이터 페칭중인 페이지를 보여줄 수 있습니다. 따라서 유저는 전체 페이지로 렌더링 되기를 안 기다려도 됩니다.React는 최근 Promise를 다루는 새로운 방법을 제시했습니다.이것들은 UI, 에러처리, 로딩처리를 손쉽게해줍니다.<aside> 💡 기존에 사용하던 getServerSideProps, getStaticProps, getIniotialProps같은 데이터 페칭 메소드들은 app directory 방식에서는 사용할 수 없습니다.The fetch() API
          • React는 자동으로 request 중복 제거를 제공합니다.
          • Next.js는 fetch에 캐싱과 재전송 옵션을 제공합니다.
          Fetching Data on the Server
          • DB 등에 바로 접근할 수있다.
          • 토큰 등의 보안이 더 강화된다.
          • 같은 환경에서 데이터를 fetch하고 렌더링합니다. 이건 클라이언트와 서버간 연결을 감소 시켜, 클라이언트의 메인스레드 효율이 더욱 좋아집니다.
          • 클라이언트에서 여러 개별요청을 날리는 것보다 하나를 round-trip돌리는 것이 더 효율적입니다.
          • client-server waterfall을 줄일 수 있습니다.
          • 지역에 따라 가까운 곳에 페칭을 날려서 성능을 향상 시킬 수 있습니다.
          Component-level Data Fetching<aside> 💡 데이터를 부모레이아웃과 자식간에 데이터가 오가는 것은 불가능합니다. 같은 경로에서 같은 데이터를 여러번 호출하더라도 필요한 컴포넌트에서 바로 데이터 페치하기를 권장합니다. 어차피 중복 요청들은 캐시되고 삭제됩니다.Parallel and Sequentail Data Fetching
          • Parallel data fetching : 요청들은 시작되고 데이터를 받아오는것이 동시에 진행됩니다. 이는 클라이언트와 서버간 waterfall을 감소시키고 전체시간을 감소시킵니다.
          • Sequentail datafetching : 요청들은 다른 요청들이 끝나는 것에 의존합니다. 요처으이 결과가 이전 요청의 결과에 의존하고 있을 때 발생합니다. 하지만 로드가 오래걸리는 것 처럼 보일 수 있습니다.
          Automatic fetch() Request Deduping
          • 서버에서 캐쉬는 렌더링 프로세스가 끝날 때까지 서버 리퀘스트의 라이프타임지송합니다.
            • 이러한 최적화는 Layouts, Pages, Server Components, generateMetadata, generateStaticParams에서 발생합니다.
            • 이러한 최적화는 static 렌더링에서 적용됩니다.
          • 클라이언트에선, 캐쉬는 모든 페이지들이 리로드되기전에 유지됩니다.
          <aside> 💡 POST는 적용 안됩니다.<aside> 💡 fetch를 사용하지 않는다면, React는 cache function을 제공하는데 이를 이요해보세요.Static and Dynamic Data Fetches
          • Static Data의 경우에는 바귀지 않는 데이터입니다.
          • Dynamic Data는 바뀌는 데이터입니다.
          Next.js는 자동적으로 static 을 fetch합니다. 이것은 데이터가 빌드 될때 fetch되면 캐싱되고 재사용되는 것을 의미합니다.
          1. 리퀘스트수를 줄여 로드 시간을 최소화합니다.
          2. 데이터가 캐싱되서 성능이 향상됩니다.
          하지만 항상 최신 데이터가 필요하다면, dynamic으로 캐싱없이 사용해야합니다.캐싱은 로컬에 데이터를 저장하는 프로세스이기 대문에 리패치를할 이유가 없습니다. Next.js 의 캐시는 HTTP캐시로 글로벌적으로 배포됩니다. 이는 캐시가 자동적으로 스케일링되고, 개발자의 플랫폼에 의존해서 여러 지역을 걸쳐서 공유될 수 있습니다.서버렌더링동안, Next.js는 fetch를 하는 동안 이미 데이터가 불러와진적 있는지 캐시를 확인합니다. 만약 내역이 있다면 캐시된 데이터가 반환되고, 아니라면 요청을 통해 데이터를 가져옵니다.</aside>Revalidating은 캐시를 지우고 데이터를 최신화하는 과정입니다. 이는 데이터가 최신 데이터인것을 보증하는데 쓰입니다.
          • Background : 특정시간마다
          • On-demand : 매번
          Streaming and Suspensenested Layout과 함께, 필요한 데이터 없이 페이지를 렌더링할 수 있고, 로딩화면을 보여줄 수 있습니다. 이것은 사용성을 높여줍니다.<aside> 💡 React team에서 개발된 내용으로 해당 내용을 참고해주시길 바랍니다.<aside> 💡 안정된 버전이 아니며, 계속해서 업데이트가 반영될 예정입니다.React와 Next.js 13은 데이터를 관리하고 fetch하는데 새로운 방식을 소개합니다. 새로운 데이터 fetching 시스템은 app directory에서 작동하고, fetch Web API로 구성되어 있습니다.async/await in Server Components
          // app/page.tsx
          async function getData() {
          	const res = await fetch('...');
          	return res.json();
          }
          
          export default async function Page(){
          	const data = await getData();
          
          	return <div></div>;
          }
          
          <aside> 💡 async Server Component는 ‘Promise<Element>’ is not a valid JSX element 를 방생시킵니다. 해당 에러는 현재 작업중입니다. 임시적으로 작업하기 위해 컴포넌트 상단에 {/* @ts-expect-error Async Server Component */} 해당 옵션을 추가하세요.Server Component Functions
          • cookies()
          • headers()
          use in Client ComponnentsStatic Data FetchingRevalidating DataDynamic Data FetchingData Fetching Patternsclient-server의 waterfall를 최소화하기 위해서, 아래와 같은 패턴을 추천합니다.Server Component에서 await를 호출하기 전에 fetch를 시착하게되면, 각 요청은 동시에 시작할 수 있습니다. 이를 통해 water fall들을 피할 수 있습니다.사용자 경험을 높이기 위해서, suspense boundary를 추가해 렌더링을 분할하고, 빨리 결과의 일부를 표시할 수 있습니다.Sequential Data Fetching
          async function Playlists({ artistID }) {
          	// Wait for the playlists
          	const playlists = await getArtistPlaylists(artistID);
          	
          	return (
          		<ul>
          			{playlist.map((playlist) => (
          				<li key={playlist.id}>{playlist.name}</li>
          			))}
          		</ul>
          	);
          }
          
          export default async function Page({ params: { username } }) {
          	// Wait for the artist
          	const artist = await getArtist(username);
          	
          	return (
          		<>
          			<h1>{artist.name}</h1>
          			<Suspnese fallback={<div>Loading...</div>}>
          				<Playlists artistID={artist.id} />
          			</Suspense>
          		</>
          	);
          }
          
          만약 컴포넌트안에서 fetching이 발생하게되면, 각 요청들을 이전 요청이 끝나기전까지 시작하지 못합니다.layout에서 fetch를 하게되며 ㄴ해당 동작이 끝나야만 아래 컴포넌트나 페이지들의 동작이 발생합니다.app directory에서는 추가적이 ㄴ옵션이 있습니다.
          1. 첫번째로 loading.js를 통해서 서버에서 결과데이터가 오기전까지 보여줄 수 있습니다.
          2. 두번째는 필요한 곳들만 막고 렌더링화면을 보여주는 방식이 있습니다.
          무엇을 하든 가장 좋은반법은 부분적으로 하는 방식일 것입니다. 이건 부분적으로 로딩페이지만을 보여주어 사용성을 높일 수 있습니다.third-party library를 사용한다면 매번 직접 다루어야할 필요없습니다.Default Caching Behavior만약 static일경우네는 캐싱되고 revalidated되지만, 동적일 경우 캐싱되지않고, 모든요청에 유효성검사를 합니다.서드파티 쿼리들이 확인되서 캐싱되기전까지, segment configuration을 임시로 사용할 수 있습니다.Intorducing Turbopack(Alpha)next/image
          • client side 부하 감소
          • 스타일링 용이
          • 플랫폼에 맞게 조절
          • hydration 불필요
          next/font
          • 자동 최적화
          • 외부 네트워크 요청을 제거하여 성능 향상
          • 자동 셀프 호스팅 기능
          • css size-adjust 속성을 통해 자동 이동
          next/linkOG Image Generation
          • Performance : 빠르게 만들 수 있습니다.
          • Ease of use : HTML과 CSS를 이용하여 할 수 있습니다.
          • Cost-effectiveness : 캐싱등을 통해 비용 절감이 가능합니다.
          Middleware API Updates헤더에 값을 추가하는 예시입니다.Bearking Changes
          • 최소 React 버전이 17.0.2에서 18.2.0으로 올라갔습니다.
          • Node.js 최소 버전이 12.22.0dptj 14.6.0으로 올라갔습니다.
          • swcMinify옵션이 false에서 true로 기본값이 바뀌었습니다.
          • next/image의 import 경로가 바뀌었습니다.
          • next/link에 a태그를 더이상 추가할 필요 없습니다.
          • User-Agent가 bot일 때 더이상 경로를 prefetch하지 않습니다.
          • next.config.js의 target옵션이 사라졌습니다.
          • IE 지원이 종료되었고, 브라우저들 버전이 올라왔습니다.
        • // middleware.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const requestHeaders = new Headers(request.headers); requestHeaders.set('x-version', '13'); const response = NextResponse.next({ request: { headers: requestHeaders, }, }); response.headers.set('x-version', '13'); return response; }
        • 12에도 미들웨어가 있었지만, 13에선 더욱 발전했습니다.
        • 오픈 그래프 이미지 생성을 Vercel을 통해서 소셜 카드 이미지를 만들수 있습니다.
        • a를 더이상 자식에 넣을 필요가 없습니다.
        • 새로운 이미지 컴포넌트를 출시했습니다.
        • webpack의 후계자인 Turbopack을 통해서 많은 속도 향상이 일어났습니다.
        • // app/page.tsx import prisma from './lib/prisma'; export const revalidate = 3600; async function getPost() { const posts = await prisma.post.findMany(); return posts; } export default async function Page(){ const posts = await getPosts(); ... }
        • Segment Cache Configuration
        • data fetching 라이브러리들은 라우크 캐싱에 잊ㄱ접 영햘을 키지지 않고, 경로에 따라 static이나 dynamic입니다.
        • fetch를 사용할수가 없지만, 여전히 캐신이나 revalidating을 사용하고 싶을 때 caching이나 caching확인을 사요하면 됩니다.
        • Data Fetching without fetch()
        • pages directory에서는 page는 getServerSideProps가 내려올때까지 loading spinner를 발생시켰습니다. 이건 전부 혹은 없ㄴ느 방식입니다.
        • Blocking Rendering in a Route
        • fetch data를 순서대로하기위해서, 컴포넌트에서 할수도 있고, await를 통해서 기다릴 수도 있습니다.
        • export default async function Page({ params: {username}}){ // Initiate both requrests in parallel const artistData = getArtist(username); const albumData = getArtistAlbums(username); // Wait for the artist's promise to resolve first const artist = await artistData; return ( <> <h1>{artist.name}</h1> {/* Send the artist information first and wrap albums in a suspense boundary */} <Suspense fallback={<div>Loading...</div>}> <Albums promise={albumData} /> </Suspense> </> ); } // Albums Component async function Albums({ promise }) { // wait for the albums promise to resolve const albums = await promise; return ( <ul> {albums.map((album) => ( <li key={album.id}>{album.name}</li> ))} </ul> ); }
        • 두 요청을 동시에 시작해서 시간을 아낄 수 있지만, 모든것이 불러오기전까지 렌더링할 수 없습니다.
        • //app/artist/[username]/page.jsx import Albums from './albums'; async function getArtist(username) { const res = await fetch(`https://api.example.com/artist/${username}`); return res.json(); } async function getArtistAlbums(username) { const res = await fetch(`https://api.example.com/artist/${username}/albums`); return res.json(); } export default async function Page({ params: {username} }){ // Initiate both requests in parallel const artistData = getArtist(username); albumsData = getArtistAlbums(username); //Wait for the promises to resolve const [artist, albums] = await Promise.all([artiestData, albumsData]); return ( <>{artist.name} ); }
        • Parallel Data Fetching
        • 모든 요청마다 데이터를 새로고침하려면 cache: ‘no-store’옵션을 사용하세요.
        • 캐쉬된 데이터를 interval로 확ㅇ니하려면, next.revalidate옵션을 통해 시간을 설정할 수 있습니다.
        • 기본적으로 fetch는 데이터를 자동으로 가져오고 무제한으로 캐시합니다.
        • use 는 await와 유사한 함수입니다. use는 promise를 컴포넌트, hooks, Suspesne와 함께 사용하는 방법을 제공합니다.
        • Next.js는 서버 컴포넌트에서 사용할 수 있는 2가지 함수를 제공합니다.
        • </aside>
        • React RFC의 목적과 함께, 서버 컴포넌트에서 async와 await를 사용할 수 있습니다.
        • fetch()는 promise로 리턴되는 fetch remote resource에 사용되는 WEB API입니다. React는 fetch를 발전시켜 자동적으로 중복 요청을 제거하고, next.js는 캐싱과 revalidating을 할 수 있는 추가 옵션을 제공합니다.
        • </aside>
        • </aside>
        • Data Fetching
        • Streaming과 suspense은 클라이언트에서 렌더링화면 등을 보여주는 리엑트의 특징입니다.
        • Next.js는 2가지 방법을 제공합니다.
        • Reavalidating Data
        • <aside> 💡 fetch를 사용할 수 없다면, React는 cache함수를 제공하니 이를 이요해보세요.
        • Next.js는 fetch 함수의 옵션을 통해 서버의 각 요청에 영구 캐싱을 설정할 수 있습니다. 컴포넌트레벨의 데이터페칭과함게 이건 너의 어플리케이션코드가 데이터가 사용되는 곳에서 캐싱할 수 있도록 해줍니다.
        • Caching Data
        • 이건 2가지 이점이 있습니다.
        • </aside>
        • </aside>
        • 만약 여러 컴포넌트들에서 같은 API들을 호출하게ㅗ딜 경우, Next.js는 자동적으로 요청들을 캐싱하고 중복 호출을 방지합니다.
        • 컴포넌트안에서 데이터가 fetching될 때 2가지 데이터 페칭 패턴에대해서 알아야 한다. (Parallel 과 Sequential)
        • </aside>
        • layout, page, component들에서 데이터 페이차 가능합니다. 또한 Sreaming과 suspense와 호환됩니다.
        • 가능한 데이터 fetching은 서버 컴포넌트에서 할 것을 권장합니다. 아래와 같은 장점이 있습니다.
        • 새로운 data fetching 시스템은 native fetch() 웹 API로 구현되었고, 서버 컴포넌트에선 async/await를 사용합니다.
        • </aside>
        • Data Fetching Fundamentals
        • native fetch Web API는 React 와 Next.js에서 강화되었습니다. 자동적으로 중복 fetch를 제거하고, fetch, cache, 재검증 데이터등을 컴포넌트레벨에서 제공합니다. 이것을 SSG, SSR, ISR에서 바로 사용할 수 있습니다.
        • Data Fetching
        • Streaming
        • 페이지나 레이아웃 사이에서 fetch 데이터를 공유하기를 원할 수 도 있습니다. 이는 불필요한 결합들을 야기할 수 있습니다.
        • import ThemeProvider from './theme-provider'; exprot default function RootLayout({children}){ return ( <html> <body> <ThemeProvider>{children}</ThemeProvider> </body> </html> ); }
        • 클라이언트 컴포넌트에선 사용가능하기 때문에 이를 이용해야합니다. 컨텍스트 provider는 응용프로그램의 루트 근처에 렌더링 되기 때문에 클라이언트 컴포넌트에서 다로 래핑한 다음 사용해야 합니다.
        • 대부분의 React 어플리에키션에선 context를 통해서 데이터를 전달하는데, Next.js의 서버 컴포넌트에선 이를 사용할 수 없습니다.
        • 특별한 경우가 없다면 서버에서 데이터를 가져오길 권장하고 있습니다.
        • 'use client' // carousel.js import { AcmeCarousel } from 'acme-carousel'; export default AcmeCarousel;
        • Third-party packages
        • Moving Client Components to the Leaves
        • 이때 server-only 라이브러리를 사용하게 된다면, 해당 코드는 클라이언트에선 사용할 수 없음을 빌드에서 알려줍니다.
        • js 모듈은 서버 컴포넌트와 클라이언트 컴포넌트가 공유하기 때문에, 서버에서만실행되도록 한 코드가 클라이언트에 들어갈 수 있습니다.
        • 서버 컴포넌트에서 클라이언트 컴포넌트로 props이 전달될 때는 시리얼화되어야 합니다. 즉 함수 등을 직접 전달할 수 없습니다.
        • 'use client' export default function Clientcomponent({children}){ return ( <> {children} </> ) }
        • 서버컴포넌트와 클라이언트 컴포넌트는 같은 컴포넌트 트리로 만들 수 있지만, 서버 컴포넌트가 서버 전용 코드를 가질 수 있어 클라이언트 컴포넌트 내에 가져오는데는 제한이 있습니다.
        • When to use Server vs. Client Components?
        • Convention
        • Client components
        • 루트가 Next.js로 로드되면 초기 HTML이 서버에 렌더링 되고, 이후 비동기로 로드를해 추가적인 인터렉션을 구현합니다.
        • Why Server Components?
        • Server Components
        • 서버에서 페이지를 렌더링하는것은 2가지 타입이 있습니다.
        • 동적 렌더링은 서버와 클라이언트 컴포넌트 모두가 서버에서 렝더링되며 캐싱되지 않습니다.
        • Static Rendering에서는 서버컴포넌트와 클라이언트 컴포넌트 모두 서버에서 빌드됩니다. 해당 빌드 파일은 클라이언트에서 캐싱되고, 재사용됩니다.
        • Next.js는 static과 dynamic rendring을 통해 렌더링 최적화 옵션을 제공합ㄴ디ㅏ.
        • Static and Dynamic Rendering on the Server
        • 아래 그림을 보면 이해가 쉽습니다.
        • app directory는 서버 컴포넌트를 기본으로 사용하고, 클라이언트에 보내는 js의 양을 줄일 수 있습니다.
        • 그래서 기존 Next.js에서는 페이지에서 쉽게 재구성할 수있는 방법을 제공했고, 서버에서 HTML을 프리렌더했고, 클라이언트에 리액트에 의해서 hydrate되도록 제공했습니다. 하지만 이 방법은 초기 HTML에서 추가적인 js 로직이 동작해야 합니다.
        • Component-level Client and Server Rendering
        • 경로가 로드 되면, Next.js와 React 런타임이 로드되는데 이는 캐시가 가능하고, 사이즈 예측이 가능합니다. 이 런타임은 프로젝트 크기가 커져도 변함이 없습니다. 또한 런타임은 비동기로 로드되고, 서버에 있던 HTML이 클라이언트에서 추가될 수 있습니다.
        • app directory는 React에서 새로나온 Server Components architecture를 지원합니다. Server and Client Components는 서버와 클라이언트에서 각자 최적의 상태로 작동합니다.
        • 형제 경로 간 이동할 때 Nextjs는 레이아웃과 페이지를 변경된 부분만 불러냅니다. 이를 통해 중복 렌더링과 패치를 막을 수 있습니다.
        • 추가적으로 라우터는 클라이언트 캐시에 서버 컴포넌트의 결과를 저장해둡니다. 이 캐시는 경로 세그먼트에 의해서 쪼개져서 모든 레벨에서 무효화를 허용하고, 렌더링 간에 일관성을 보장합니다. 따라서 이전에 가져온 세그먼트의 캐시를 사용해 성능을 더욱 향상 시킬 수 있습니다.
        • pages directory방식이 client-side routing을 사용하는 것과 달리, app directory방식은 Server Component와 서버에서 데이터 fetching을 통한 server-centric routing 방식을 사용합니다. server-centric-routing은 클라이언트가 경로 맵을 다운받을 필요가 없으며, 서버에서 해당 로직을 처리할 수 있습니다. 이러한 최적화는 많은 경로를 가진 프로그램일수록 더욱 좋습니다.
        • 위에서 살펴본 파일들에더해서 추가로 여러 파일들을 폴더 속에 포함 시킬 수 있습니다. 예시로 styleshhets, tests, components등등이 있습니다.
        • 이를 폴더들을 첨가한다면 아래와 같이 나타납니다.
        • 위에서 살펴본 파일들의 계층 구조를 설명합니다.
        • File Conventions
        • Folders : 폴더들은 경로를 규정하는데 사용됩니다. pages.js가 포함된 root 폴더에서 leaf폴더까지 계층 구조를 가지고, 이를 통해 single path를 만들어냅니다.
        • 기본적으로 app 은 React Server Components입니다. 이건 성능적으로 좋고, 쉽게 선택할 수 있지만, Client Components도 사용해야 합니다.
        • 새로운 router 방식은 app으로 명명되었습니다. app directory는 pages directory가 남아있는 과정에서 실험적으로 채택되었습니다. 이 방식을 통해 일부 router를 새로운 방식으로 동작하도록 하고, 나머지는 이전 동작 방식을 유지할 수 있습니다.
        • 자세히 살펴 보면 아래와 같습니다. (생략한 항목들이 있으니, 시간이 되신다면 원문을 읽어보시길 추천합니다. 😊)
        • export default function Page() { return ( <h1> Hello, Next.js! </h1> ) }
        • app/을 통해서 navigation 전반에서 상태를 유지하고, 리렌더링을 방지하고, 고급 라우팅 패턴을 사용할 수 있습니다. 또한 레이아웃을 중첩 할 수 있고, 컴포넌트, 테스트 및 스타일과 같은 코드들을 어플리케이션 코드에 같은 곳에 배치할 수 있습니다.
        • app directory는 현재 베타 버전이고, PR에는 추천하지 않습니다. 그리고 아직 pages directory는 next/image와 next/link 등 기존의 안정된 기능들과 함께 사용할 수 있습니다.
      • // middleware.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const requestHeaders = new Headers(request.headers); requestHeaders.set('x-version', '13'); const response = NextResponse.next({ request: { headers: requestHeaders, }, }); response.headers.set('x-version', '13'); return response; }
      • 12에도 미들웨어가 있었지만, 13에선 더욱 발전했습니다.
      • 오픈 그래프 이미지 생성을 Vercel을 통해서 소셜 카드 이미지를 만들수 있습니다.
      • a를 더이상 자식에 넣을 필요가 없습니다.
      • 새로운 이미지 컴포넌트를 출시했습니다.
      • webpack의 후계자인 Turbopack을 통해서 많은 속도 향상이 일어났습니다.
      • // app/page.tsx import prisma from './lib/prisma'; export const revalidate = 3600; async function getPost() { const posts = await prisma.post.findMany(); return posts; } export default async function Page(){ const posts = await getPosts(); ... }
      • Segment Cache Configuration
      • data fetching 라이브러리들은 라우크 캐싱에 잊ㄱ접 영햘을 키지지 않고, 경로에 따라 static이나 dynamic입니다.
      • fetch를 사용할수가 없지만, 여전히 캐신이나 revalidating을 사용하고 싶을 때 caching이나 caching확인을 사요하면 됩니다.
      • Data Fetching without fetch()
      • pages directory에서는 page는 getServerSideProps가 내려올때까지 loading spinner를 발생시켰습니다. 이건 전부 혹은 없ㄴ느 방식입니다.
      • Blocking Rendering in a Route
      • fetch data를 순서대로하기위해서, 컴포넌트에서 할수도 있고, await를 통해서 기다릴 수도 있습니다.
      • export default async function Page({ params: {username}}){ // Initiate both requrests in parallel const artistData = getArtist(username); const albumData = getArtistAlbums(username); // Wait for the artist's promise to resolve first const artist = await artistData; return ( <> <h1>{artist.name}</h1> {/* Send the artist information first and wrap albums in a suspense boundary */} <Suspense fallback={<div>Loading...</div>}> <Albums promise={albumData} /> </Suspense> </> ); } // Albums Component async function Albums({ promise }) { // wait for the albums promise to resolve const albums = await promise; return ( <ul> {albums.map((album) => ( <li key={album.id}>{album.name}</li> ))} </ul> ); }
      • 두 요청을 동시에 시작해서 시간을 아낄 수 있지만, 모든것이 불러오기전까지 렌더링할 수 없습니다.
      • //app/artist/[username]/page.jsx import Albums from './albums'; async function getArtist(username) { const res = await fetch(`https://api.example.com/artist/${username}`); return res.json(); } async function getArtistAlbums(username) { const res = await fetch(`https://api.example.com/artist/${username}/albums`); return res.json(); } export default async function Page({ params: {username} }){ // Initiate both requests in parallel const artistData = getArtist(username); albumsData = getArtistAlbums(username); //Wait for the promises to resolve const [artist, albums] = await Promise.all([artiestData, albumsData]); return ( <>{artist.name} ); }
      • Parallel Data Fetching
      • 모든 요청마다 데이터를 새로고침하려면 cache: ‘no-store’옵션을 사용하세요.
      • 캐쉬된 데이터를 interval로 확ㅇ니하려면, next.revalidate옵션을 통해 시간을 설정할 수 있습니다.
      • 기본적으로 fetch는 데이터를 자동으로 가져오고 무제한으로 캐시합니다.
      • use 는 await와 유사한 함수입니다. use는 promise를 컴포넌트, hooks, Suspesne와 함께 사용하는 방법을 제공합니다.
      • Next.js는 서버 컴포넌트에서 사용할 수 있는 2가지 함수를 제공합니다.
      • </aside>
      • React RFC의 목적과 함께, 서버 컴포넌트에서 async와 await를 사용할 수 있습니다.
      • fetch()는 promise로 리턴되는 fetch remote resource에 사용되는 WEB API입니다. React는 fetch를 발전시켜 자동적으로 중복 요청을 제거하고, next.js는 캐싱과 revalidating을 할 수 있는 추가 옵션을 제공합니다.
      • </aside>
      • </aside>
      • Data Fetching
      • Streaming과 suspense은 클라이언트에서 렌더링화면 등을 보여주는 리엑트의 특징입니다.
      • Next.js는 2가지 방법을 제공합니다.
      • Reavalidating Data
      • <aside> 💡 fetch를 사용할 수 없다면, React는 cache함수를 제공하니 이를 이요해보세요.
      • Next.js는 fetch 함수의 옵션을 통해 서버의 각 요청에 영구 캐싱을 설정할 수 있습니다. 컴포넌트레벨의 데이터페칭과함게 이건 너의 어플리케이션코드가 데이터가 사용되는 곳에서 캐싱할 수 있도록 해줍니다.
      • Caching Data
      • 이건 2가지 이점이 있습니다.
      • </aside>
      • </aside>
      • 만약 여러 컴포넌트들에서 같은 API들을 호출하게ㅗ딜 경우, Next.js는 자동적으로 요청들을 캐싱하고 중복 호출을 방지합니다.
      • 컴포넌트안에서 데이터가 fetching될 때 2가지 데이터 페칭 패턴에대해서 알아야 한다. (Parallel 과 Sequential)
      • </aside>
      • layout, page, component들에서 데이터 페이차 가능합니다. 또한 Sreaming과 suspense와 호환됩니다.
      • 가능한 데이터 fetching은 서버 컴포넌트에서 할 것을 권장합니다. 아래와 같은 장점이 있습니다.
      • 새로운 data fetching 시스템은 native fetch() 웹 API로 구현되었고, 서버 컴포넌트에선 async/await를 사용합니다.
      • </aside>
      • Data Fetching Fundamentals
      • native fetch Web API는 React 와 Next.js에서 강화되었습니다. 자동적으로 중복 fetch를 제거하고, fetch, cache, 재검증 데이터등을 컴포넌트레벨에서 제공합니다. 이것을 SSG, SSR, ISR에서 바로 사용할 수 있습니다.
      • Data Fetching
      • Streaming
      • 페이지나 레이아웃 사이에서 fetch 데이터를 공유하기를 원할 수 도 있습니다. 이는 불필요한 결합들을 야기할 수 있습니다.
      • import ThemeProvider from './theme-provider'; exprot default function RootLayout({children}){ return ( <html> <body> <ThemeProvider>{children}</ThemeProvider> </body> </html> ); }
      • 클라이언트 컴포넌트에선 사용가능하기 때문에 이를 이용해야합니다. 컨텍스트 provider는 응용프로그램의 루트 근처에 렌더링 되기 때문에 클라이언트 컴포넌트에서 다로 래핑한 다음 사용해야 합니다.
      • 대부분의 React 어플리에키션에선 context를 통해서 데이터를 전달하는데, Next.js의 서버 컴포넌트에선 이를 사용할 수 없습니다.
      • 특별한 경우가 없다면 서버에서 데이터를 가져오길 권장하고 있습니다.
      • 'use client' // carousel.js import { AcmeCarousel } from 'acme-carousel'; export default AcmeCarousel;
      • Third-party packages
      • Moving Client Components to the Leaves
      • 이때 server-only 라이브러리를 사용하게 된다면, 해당 코드는 클라이언트에선 사용할 수 없음을 빌드에서 알려줍니다.
      • js 모듈은 서버 컴포넌트와 클라이언트 컴포넌트가 공유하기 때문에, 서버에서만실행되도록 한 코드가 클라이언트에 들어갈 수 있습니다.
      • 서버 컴포넌트에서 클라이언트 컴포넌트로 props이 전달될 때는 시리얼화되어야 합니다. 즉 함수 등을 직접 전달할 수 없습니다.
      • 'use client' export default function Clientcomponent({children}){ return ( <> {children} </> ) }
      • 서버컴포넌트와 클라이언트 컴포넌트는 같은 컴포넌트 트리로 만들 수 있지만, 서버 컴포넌트가 서버 전용 코드를 가질 수 있어 클라이언트 컴포넌트 내에 가져오는데는 제한이 있습니다.
      • When to use Server vs. Client Components?
      • Convention
      • Client components
      • 루트가 Next.js로 로드되면 초기 HTML이 서버에 렌더링 되고, 이후 비동기로 로드를해 추가적인 인터렉션을 구현합니다.
      • Why Server Components?
      • Server Components
      • 서버에서 페이지를 렌더링하는것은 2가지 타입이 있습니다.
      • 동적 렌더링은 서버와 클라이언트 컴포넌트 모두가 서버에서 렝더링되며 캐싱되지 않습니다.
      • Static Rendering에서는 서버컴포넌트와 클라이언트 컴포넌트 모두 서버에서 빌드됩니다. 해당 빌드 파일은 클라이언트에서 캐싱되고, 재사용됩니다.
      • Next.js는 static과 dynamic rendring을 통해 렌더링 최적화 옵션을 제공합ㄴ디ㅏ.
      • Static and Dynamic Rendering on the Server
      • 아래 그림을 보면 이해가 쉽습니다.
      • app directory는 서버 컴포넌트를 기본으로 사용하고, 클라이언트에 보내는 js의 양을 줄일 수 있습니다.
      • 그래서 기존 Next.js에서는 페이지에서 쉽게 재구성할 수있는 방법을 제공했고, 서버에서 HTML을 프리렌더했고, 클라이언트에 리액트에 의해서 hydrate되도록 제공했습니다. 하지만 이 방법은 초기 HTML에서 추가적인 js 로직이 동작해야 합니다.
      • Component-level Client and Server Rendering
      • 경로가 로드 되면, Next.js와 React 런타임이 로드되는데 이는 캐시가 가능하고, 사이즈 예측이 가능합니다. 이 런타임은 프로젝트 크기가 커져도 변함이 없습니다. 또한 런타임은 비동기로 로드되고, 서버에 있던 HTML이 클라이언트에서 추가될 수 있습니다.
      • app directory는 React에서 새로나온 Server Components architecture를 지원합니다. Server and Client Components는 서버와 클라이언트에서 각자 최적의 상태로 작동합니다.
      • 형제 경로 간 이동할 때 Nextjs는 레이아웃과 페이지를 변경된 부분만 불러냅니다. 이를 통해 중복 렌더링과 패치를 막을 수 있습니다.
      • 추가적으로 라우터는 클라이언트 캐시에 서버 컴포넌트의 결과를 저장해둡니다. 이 캐시는 경로 세그먼트에 의해서 쪼개져서 모든 레벨에서 무효화를 허용하고, 렌더링 간에 일관성을 보장합니다. 따라서 이전에 가져온 세그먼트의 캐시를 사용해 성능을 더욱 향상 시킬 수 있습니다.
      • pages directory방식이 client-side routing을 사용하는 것과 달리, app directory방식은 Server Component와 서버에서 데이터 fetching을 통한 server-centric routing 방식을 사용합니다. server-centric-routing은 클라이언트가 경로 맵을 다운받을 필요가 없으며, 서버에서 해당 로직을 처리할 수 있습니다. 이러한 최적화는 많은 경로를 가진 프로그램일수록 더욱 좋습니다.
      • 위에서 살펴본 파일들에더해서 추가로 여러 파일들을 폴더 속에 포함 시킬 수 있습니다. 예시로 styleshhets, tests, components등등이 있습니다.
      • 이를 폴더들을 첨가한다면 아래와 같이 나타납니다.
      • 위에서 살펴본 파일들의 계층 구조를 설명합니다.
      • File Conventions
      • Folders : 폴더들은 경로를 규정하는데 사용됩니다. pages.js가 포함된 root 폴더에서 leaf폴더까지 계층 구조를 가지고, 이를 통해 single path를 만들어냅니다.
      • 기본적으로 app 은 React Server Components입니다. 이건 성능적으로 좋고, 쉽게 선택할 수 있지만, Client Components도 사용해야 합니다.
      • 새로운 router 방식은 app으로 명명되었습니다. app directory는 pages directory가 남아있는 과정에서 실험적으로 채택되었습니다. 이 방식을 통해 일부 router를 새로운 방식으로 동작하도록 하고, 나머지는 이전 동작 방식을 유지할 수 있습니다.
      • 자세히 살펴 보면 아래와 같습니다. (생략한 항목들이 있으니, 시간이 되신다면 원문을 읽어보시길 추천합니다. 😊)
      • export default function Page() { return ( <h1> Hello, Next.js! </h1> ) }
      • app/을 통해서 navigation 전반에서 상태를 유지하고, 리렌더링을 방지하고, 고급 라우팅 패턴을 사용할 수 있습니다. 또한 레이아웃을 중첩 할 수 있고, 컴포넌트, 테스트 및 스타일과 같은 코드들을 어플리케이션 코드에 같은 곳에 배치할 수 있습니다.
      • app directory는 현재 베타 버전이고, PR에는 추천하지 않습니다. 그리고 아직 pages directory는 next/image와 next/link 등 기존의 안정된 기능들과 함께 사용할 수 있습니다.
    • // middleware.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const requestHeaders = new Headers(request.headers); requestHeaders.set('x-version', '13'); const response = NextResponse.next({ request: { headers: requestHeaders, }, }); response.headers.set('x-version', '13'); return response; }
    • 12에도 미들웨어가 있었지만, 13에선 더욱 발전했습니다.
    • 오픈 그래프 이미지 생성을 Vercel을 통해서 소셜 카드 이미지를 만들수 있습니다.
    • a를 더이상 자식에 넣을 필요가 없습니다.
    • 새로운 이미지 컴포넌트를 출시했습니다.
    • webpack의 후계자인 Turbopack을 통해서 많은 속도 향상이 일어났습니다.
    • // app/page.tsx import prisma from './lib/prisma'; export const revalidate = 3600; async function getPost() { const posts = await prisma.post.findMany(); return posts; } export default async function Page(){ const posts = await getPosts(); ... }
    • Segment Cache Configuration
    • data fetching 라이브러리들은 라우크 캐싱에 잊ㄱ접 영햘을 키지지 않고, 경로에 따라 static이나 dynamic입니다.
    • fetch를 사용할수가 없지만, 여전히 캐신이나 revalidating을 사용하고 싶을 때 caching이나 caching확인을 사요하면 됩니다.
    • Data Fetching without fetch()
    • pages directory에서는 page는 getServerSideProps가 내려올때까지 loading spinner를 발생시켰습니다. 이건 전부 혹은 없ㄴ느 방식입니다.
    • Blocking Rendering in a Route
    • fetch data를 순서대로하기위해서, 컴포넌트에서 할수도 있고, await를 통해서 기다릴 수도 있습니다.
    • export default async function Page({ params: {username}}){ // Initiate both requrests in parallel const artistData = getArtist(username); const albumData = getArtistAlbums(username); // Wait for the artist's promise to resolve first const artist = await artistData; return ( <> <h1>{artist.name}</h1> {/* Send the artist information first and wrap albums in a suspense boundary */} <Suspense fallback={<div>Loading...</div>}> <Albums promise={albumData} /> </Suspense> </> ); } // Albums Component async function Albums({ promise }) { // wait for the albums promise to resolve const albums = await promise; return ( <ul> {albums.map((album) => ( <li key={album.id}>{album.name}</li> ))} </ul> ); }
    • 두 요청을 동시에 시작해서 시간을 아낄 수 있지만, 모든것이 불러오기전까지 렌더링할 수 없습니다.
    • //app/artist/[username]/page.jsx import Albums from './albums'; async function getArtist(username) { const res = await fetch(`https://api.example.com/artist/${username}`); return res.json(); } async function getArtistAlbums(username) { const res = await fetch(`https://api.example.com/artist/${username}/albums`); return res.json(); } export default async function Page({ params: {username} }){ // Initiate both requests in parallel const artistData = getArtist(username); albumsData = getArtistAlbums(username); //Wait for the promises to resolve const [artist, albums] = await Promise.all([artiestData, albumsData]); return ( <>{artist.name} ); }
    • Parallel Data Fetching
    • 모든 요청마다 데이터를 새로고침하려면 cache: ‘no-store’옵션을 사용하세요.
    • 캐쉬된 데이터를 interval로 확ㅇ니하려면, next.revalidate옵션을 통해 시간을 설정할 수 있습니다.
    • 기본적으로 fetch는 데이터를 자동으로 가져오고 무제한으로 캐시합니다.
    • use 는 await와 유사한 함수입니다. use는 promise를 컴포넌트, hooks, Suspesne와 함께 사용하는 방법을 제공합니다.
    • Next.js는 서버 컴포넌트에서 사용할 수 있는 2가지 함수를 제공합니다.
    • </aside>
    • React RFC의 목적과 함께, 서버 컴포넌트에서 async와 await를 사용할 수 있습니다.
    • fetch()는 promise로 리턴되는 fetch remote resource에 사용되는 WEB API입니다. React는 fetch를 발전시켜 자동적으로 중복 요청을 제거하고, next.js는 캐싱과 revalidating을 할 수 있는 추가 옵션을 제공합니다.
    • </aside>
    • </aside>
    • Data Fetching
    • Streaming과 suspense은 클라이언트에서 렌더링화면 등을 보여주는 리엑트의 특징입니다.
    • Next.js는 2가지 방법을 제공합니다.
    • Reavalidating Data
    • <aside> 💡 fetch를 사용할 수 없다면, React는 cache함수를 제공하니 이를 이요해보세요.
    • Next.js는 fetch 함수의 옵션을 통해 서버의 각 요청에 영구 캐싱을 설정할 수 있습니다. 컴포넌트레벨의 데이터페칭과함게 이건 너의 어플리케이션코드가 데이터가 사용되는 곳에서 캐싱할 수 있도록 해줍니다.
    • Caching Data
    • 이건 2가지 이점이 있습니다.
    • </aside>
    • </aside>
    • 만약 여러 컴포넌트들에서 같은 API들을 호출하게ㅗ딜 경우, Next.js는 자동적으로 요청들을 캐싱하고 중복 호출을 방지합니다.
    • 컴포넌트안에서 데이터가 fetching될 때 2가지 데이터 페칭 패턴에대해서 알아야 한다. (Parallel 과 Sequential)
    • </aside>
    • layout, page, component들에서 데이터 페이차 가능합니다. 또한 Sreaming과 suspense와 호환됩니다.
    • 가능한 데이터 fetching은 서버 컴포넌트에서 할 것을 권장합니다. 아래와 같은 장점이 있습니다.
    • 새로운 data fetching 시스템은 native fetch() 웹 API로 구현되었고, 서버 컴포넌트에선 async/await를 사용합니다.
    • </aside>
    • Data Fetching Fundamentals
    • native fetch Web API는 React 와 Next.js에서 강화되었습니다. 자동적으로 중복 fetch를 제거하고, fetch, cache, 재검증 데이터등을 컴포넌트레벨에서 제공합니다. 이것을 SSG, SSR, ISR에서 바로 사용할 수 있습니다.
    • Data Fetching
    • Streaming
    • 페이지나 레이아웃 사이에서 fetch 데이터를 공유하기를 원할 수 도 있습니다. 이는 불필요한 결합들을 야기할 수 있습니다.
    • import ThemeProvider from './theme-provider'; exprot default function RootLayout({children}){ return ( <html> <body> <ThemeProvider>{children}</ThemeProvider> </body> </html> ); }
    • 클라이언트 컴포넌트에선 사용가능하기 때문에 이를 이용해야합니다. 컨텍스트 provider는 응용프로그램의 루트 근처에 렌더링 되기 때문에 클라이언트 컴포넌트에서 다로 래핑한 다음 사용해야 합니다.
    • 대부분의 React 어플리에키션에선 context를 통해서 데이터를 전달하는데, Next.js의 서버 컴포넌트에선 이를 사용할 수 없습니다.
    • 특별한 경우가 없다면 서버에서 데이터를 가져오길 권장하고 있습니다.
    • 'use client' // carousel.js import { AcmeCarousel } from 'acme-carousel'; export default AcmeCarousel;
    • Third-party packages
    • Moving Client Components to the Leaves
    • 이때 server-only 라이브러리를 사용하게 된다면, 해당 코드는 클라이언트에선 사용할 수 없음을 빌드에서 알려줍니다.
    • js 모듈은 서버 컴포넌트와 클라이언트 컴포넌트가 공유하기 때문에, 서버에서만실행되도록 한 코드가 클라이언트에 들어갈 수 있습니다.
    • 서버 컴포넌트에서 클라이언트 컴포넌트로 props이 전달될 때는 시리얼화되어야 합니다. 즉 함수 등을 직접 전달할 수 없습니다.
    • 'use client' export default function Clientcomponent({children}){ return ( <> {children} </> ) }
    • 서버컴포넌트와 클라이언트 컴포넌트는 같은 컴포넌트 트리로 만들 수 있지만, 서버 컴포넌트가 서버 전용 코드를 가질 수 있어 클라이언트 컴포넌트 내에 가져오는데는 제한이 있습니다.
    • When to use Server vs. Client Components?
    • Convention
    • Client components
    • 루트가 Next.js로 로드되면 초기 HTML이 서버에 렌더링 되고, 이후 비동기로 로드를해 추가적인 인터렉션을 구현합니다.
    • Why Server Components?
    • Server Components
    • 서버에서 페이지를 렌더링하는것은 2가지 타입이 있습니다.
    • 동적 렌더링은 서버와 클라이언트 컴포넌트 모두가 서버에서 렝더링되며 캐싱되지 않습니다.
    • Static Rendering에서는 서버컴포넌트와 클라이언트 컴포넌트 모두 서버에서 빌드됩니다. 해당 빌드 파일은 클라이언트에서 캐싱되고, 재사용됩니다.
    • Next.js는 static과 dynamic rendring을 통해 렌더링 최적화 옵션을 제공합ㄴ디ㅏ.
    • Static and Dynamic Rendering on the Server
    • 아래 그림을 보면 이해가 쉽습니다.
    • app directory는 서버 컴포넌트를 기본으로 사용하고, 클라이언트에 보내는 js의 양을 줄일 수 있습니다.
    • 그래서 기존 Next.js에서는 페이지에서 쉽게 재구성할 수있는 방법을 제공했고, 서버에서 HTML을 프리렌더했고, 클라이언트에 리액트에 의해서 hydrate되도록 제공했습니다. 하지만 이 방법은 초기 HTML에서 추가적인 js 로직이 동작해야 합니다.
    • Component-level Client and Server Rendering
    • 경로가 로드 되면, Next.js와 React 런타임이 로드되는데 이는 캐시가 가능하고, 사이즈 예측이 가능합니다. 이 런타임은 프로젝트 크기가 커져도 변함이 없습니다. 또한 런타임은 비동기로 로드되고, 서버에 있던 HTML이 클라이언트에서 추가될 수 있습니다.
    • app directory는 React에서 새로나온 Server Components architecture를 지원합니다. Server and Client Components는 서버와 클라이언트에서 각자 최적의 상태로 작동합니다.
    • 형제 경로 간 이동할 때 Nextjs는 레이아웃과 페이지를 변경된 부분만 불러냅니다. 이를 통해 중복 렌더링과 패치를 막을 수 있습니다.
    • 추가적으로 라우터는 클라이언트 캐시에 서버 컴포넌트의 결과를 저장해둡니다. 이 캐시는 경로 세그먼트에 의해서 쪼개져서 모든 레벨에서 무효화를 허용하고, 렌더링 간에 일관성을 보장합니다. 따라서 이전에 가져온 세그먼트의 캐시를 사용해 성능을 더욱 향상 시킬 수 있습니다.
    • pages directory방식이 client-side routing을 사용하는 것과 달리, app directory방식은 Server Component와 서버에서 데이터 fetching을 통한 server-centric routing 방식을 사용합니다. server-centric-routing은 클라이언트가 경로 맵을 다운받을 필요가 없으며, 서버에서 해당 로직을 처리할 수 있습니다. 이러한 최적화는 많은 경로를 가진 프로그램일수록 더욱 좋습니다.
    • 위에서 살펴본 파일들에더해서 추가로 여러 파일들을 폴더 속에 포함 시킬 수 있습니다. 예시로 styleshhets, tests, components등등이 있습니다.
    • 이를 폴더들을 첨가한다면 아래와 같이 나타납니다.
    • 위에서 살펴본 파일들의 계층 구조를 설명합니다.
    • File Conventions
    • Folders : 폴더들은 경로를 규정하는데 사용됩니다. pages.js가 포함된 root 폴더에서 leaf폴더까지 계층 구조를 가지고, 이를 통해 single path를 만들어냅니다.
    • 기본적으로 app 은 React Server Components입니다. 이건 성능적으로 좋고, 쉽게 선택할 수 있지만, Client Components도 사용해야 합니다.
    • 새로운 router 방식은 app으로 명명되었습니다. app directory는 pages directory가 남아있는 과정에서 실험적으로 채택되었습니다. 이 방식을 통해 일부 router를 새로운 방식으로 동작하도록 하고, 나머지는 이전 동작 방식을 유지할 수 있습니다.
    • 자세히 살펴 보면 아래와 같습니다. (생략한 항목들이 있으니, 시간이 되신다면 원문을 읽어보시길 추천합니다. 😊)
    • export default function Page() { return ( <h1> Hello, Next.js! </h1> ) }
    • app/을 통해서 navigation 전반에서 상태를 유지하고, 리렌더링을 방지하고, 고급 라우팅 패턴을 사용할 수 있습니다. 또한 레이아웃을 중첩 할 수 있고, 컴포넌트, 테스트 및 스타일과 같은 코드들을 어플리케이션 코드에 같은 곳에 배치할 수 있습니다.
    • app directory는 현재 베타 버전이고, PR에는 추천하지 않습니다. 그리고 아직 pages directory는 next/image와 next/link 등 기존의 안정된 기능들과 함께 사용할 수 있습니다.
  • // middleware.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const requestHeaders = new Headers(request.headers); requestHeaders.set('x-version', '13'); const response = NextResponse.next({ request: { headers: requestHeaders, }, }); response.headers.set('x-version', '13'); return response; }
  • 12에도 미들웨어가 있었지만, 13에선 더욱 발전했습니다.
  • 오픈 그래프 이미지 생성을 Vercel을 통해서 소셜 카드 이미지를 만들수 있습니다.
  • a를 더이상 자식에 넣을 필요가 없습니다.
  • 새로운 이미지 컴포넌트를 출시했습니다.
  • webpack의 후계자인 Turbopack을 통해서 많은 속도 향상이 일어났습니다.
  • // app/page.tsx import prisma from './lib/prisma'; export const revalidate = 3600; async function getPost() { const posts = await prisma.post.findMany(); return posts; } export default async function Page(){ const posts = await getPosts(); ... }
  • Segment Cache Configuration
  • data fetching 라이브러리들은 라우크 캐싱에 잊ㄱ접 영햘을 키지지 않고, 경로에 따라 static이나 dynamic입니다.
  • fetch를 사용할수가 없지만, 여전히 캐신이나 revalidating을 사용하고 싶을 때 caching이나 caching확인을 사요하면 됩니다.
  • Data Fetching without fetch()
  • pages directory에서는 page는 getServerSideProps가 내려올때까지 loading spinner를 발생시켰습니다. 이건 전부 혹은 없ㄴ느 방식입니다.
  • Blocking Rendering in a Route
  • fetch data를 순서대로하기위해서, 컴포넌트에서 할수도 있고, await를 통해서 기다릴 수도 있습니다.
  • export default async function Page({ params: {username}}){ // Initiate both requrests in parallel const artistData = getArtist(username); const albumData = getArtistAlbums(username); // Wait for the artist's promise to resolve first const artist = await artistData; return ( <> <h1>{artist.name}</h1> {/* Send the artist information first and wrap albums in a suspense boundary */} <Suspense fallback={<div>Loading...</div>}> <Albums promise={albumData} /> </Suspense> </> ); } // Albums Component async function Albums({ promise }) { // wait for the albums promise to resolve const albums = await promise; return ( <ul> {albums.map((album) => ( <li key={album.id}>{album.name}</li> ))} </ul> ); }
  • 두 요청을 동시에 시작해서 시간을 아낄 수 있지만, 모든것이 불러오기전까지 렌더링할 수 없습니다.
  • //app/artist/[username]/page.jsx import Albums from './albums'; async function getArtist(username) { const res = await fetch(`https://api.example.com/artist/${username}`); return res.json(); } async function getArtistAlbums(username) { const res = await fetch(`https://api.example.com/artist/${username}/albums`); return res.json(); } export default async function Page({ params: {username} }){ // Initiate both requests in parallel const artistData = getArtist(username); albumsData = getArtistAlbums(username); //Wait for the promises to resolve const [artist, albums] = await Promise.all([artiestData, albumsData]); return ( <>{artist.name} ); }
  • Parallel Data Fetching
  • 모든 요청마다 데이터를 새로고침하려면 cache: ‘no-store’옵션을 사용하세요.
  • 캐쉬된 데이터를 interval로 확ㅇ니하려면, next.revalidate옵션을 통해 시간을 설정할 수 있습니다.
  • 기본적으로 fetch는 데이터를 자동으로 가져오고 무제한으로 캐시합니다.
  • use 는 await와 유사한 함수입니다. use는 promise를 컴포넌트, hooks, Suspesne와 함께 사용하는 방법을 제공합니다.
  • Next.js는 서버 컴포넌트에서 사용할 수 있는 2가지 함수를 제공합니다.
  • </aside>
  • React RFC의 목적과 함께, 서버 컴포넌트에서 async와 await를 사용할 수 있습니다.
  • fetch()는 promise로 리턴되는 fetch remote resource에 사용되는 WEB API입니다. React는 fetch를 발전시켜 자동적으로 중복 요청을 제거하고, next.js는 캐싱과 revalidating을 할 수 있는 추가 옵션을 제공합니다.
  • </aside>
  • </aside>
  • Data Fetching
  • Streaming과 suspense은 클라이언트에서 렌더링화면 등을 보여주는 리엑트의 특징입니다.
  • Next.js는 2가지 방법을 제공합니다.
  • Reavalidating Data
  • <aside> 💡 fetch를 사용할 수 없다면, React는 cache함수를 제공하니 이를 이요해보세요.
  • Next.js는 fetch 함수의 옵션을 통해 서버의 각 요청에 영구 캐싱을 설정할 수 있습니다. 컴포넌트레벨의 데이터페칭과함게 이건 너의 어플리케이션코드가 데이터가 사용되는 곳에서 캐싱할 수 있도록 해줍니다.
  • Caching Data
  • 이건 2가지 이점이 있습니다.
  • </aside>
  • </aside>
  • 만약 여러 컴포넌트들에서 같은 API들을 호출하게ㅗ딜 경우, Next.js는 자동적으로 요청들을 캐싱하고 중복 호출을 방지합니다.
  • 컴포넌트안에서 데이터가 fetching될 때 2가지 데이터 페칭 패턴에대해서 알아야 한다. (Parallel 과 Sequential)
  • </aside>
  • layout, page, component들에서 데이터 페이차 가능합니다. 또한 Sreaming과 suspense와 호환됩니다.
  • 가능한 데이터 fetching은 서버 컴포넌트에서 할 것을 권장합니다. 아래와 같은 장점이 있습니다.
  • 새로운 data fetching 시스템은 native fetch() 웹 API로 구현되었고, 서버 컴포넌트에선 async/await를 사용합니다.
  • </aside>
  • Data Fetching Fundamentals
  • native fetch Web API는 React 와 Next.js에서 강화되었습니다. 자동적으로 중복 fetch를 제거하고, fetch, cache, 재검증 데이터등을 컴포넌트레벨에서 제공합니다. 이것을 SSG, SSR, ISR에서 바로 사용할 수 있습니다.
  • Data Fetching
  • Streaming
  • 페이지나 레이아웃 사이에서 fetch 데이터를 공유하기를 원할 수 도 있습니다. 이는 불필요한 결합들을 야기할 수 있습니다.
  • import ThemeProvider from './theme-provider'; exprot default function RootLayout({children}){ return ( <html> <body> <ThemeProvider>{children}</ThemeProvider> </body> </html> ); }
  • 클라이언트 컴포넌트에선 사용가능하기 때문에 이를 이용해야합니다. 컨텍스트 provider는 응용프로그램의 루트 근처에 렌더링 되기 때문에 클라이언트 컴포넌트에서 다로 래핑한 다음 사용해야 합니다.
  • 대부분의 React 어플리에키션에선 context를 통해서 데이터를 전달하는데, Next.js의 서버 컴포넌트에선 이를 사용할 수 없습니다.
  • 특별한 경우가 없다면 서버에서 데이터를 가져오길 권장하고 있습니다.
  • 'use client' // carousel.js import { AcmeCarousel } from 'acme-carousel'; export default AcmeCarousel;
  • Third-party packages
  • Moving Client Components to the Leaves
  • 이때 server-only 라이브러리를 사용하게 된다면, 해당 코드는 클라이언트에선 사용할 수 없음을 빌드에서 알려줍니다.
  • js 모듈은 서버 컴포넌트와 클라이언트 컴포넌트가 공유하기 때문에, 서버에서만실행되도록 한 코드가 클라이언트에 들어갈 수 있습니다.
  • 서버 컴포넌트에서 클라이언트 컴포넌트로 props이 전달될 때는 시리얼화되어야 합니다. 즉 함수 등을 직접 전달할 수 없습니다.
  • 'use client' export default function Clientcomponent({children}){ return ( <> {children} </> ) }
  • 서버컴포넌트와 클라이언트 컴포넌트는 같은 컴포넌트 트리로 만들 수 있지만, 서버 컴포넌트가 서버 전용 코드를 가질 수 있어 클라이언트 컴포넌트 내에 가져오는데는 제한이 있습니다.
  • When to use Server vs. Client Components?
  • Convention
  • Client components
  • 루트가 Next.js로 로드되면 초기 HTML이 서버에 렌더링 되고, 이후 비동기로 로드를해 추가적인 인터렉션을 구현합니다.
  • Why Server Components?
  • Server Components
  • 서버에서 페이지를 렌더링하는것은 2가지 타입이 있습니다.
  • 동적 렌더링은 서버와 클라이언트 컴포넌트 모두가 서버에서 렝더링되며 캐싱되지 않습니다.
  • Static Rendering에서는 서버컴포넌트와 클라이언트 컴포넌트 모두 서버에서 빌드됩니다. 해당 빌드 파일은 클라이언트에서 캐싱되고, 재사용됩니다.
  • Next.js는 static과 dynamic rendring을 통해 렌더링 최적화 옵션을 제공합ㄴ디ㅏ.
  • Static and Dynamic Rendering on the Server
  • 아래 그림을 보면 이해가 쉽습니다.
  • app directory는 서버 컴포넌트를 기본으로 사용하고, 클라이언트에 보내는 js의 양을 줄일 수 있습니다.
  • 그래서 기존 Next.js에서는 페이지에서 쉽게 재구성할 수있는 방법을 제공했고, 서버에서 HTML을 프리렌더했고, 클라이언트에 리액트에 의해서 hydrate되도록 제공했습니다. 하지만 이 방법은 초기 HTML에서 추가적인 js 로직이 동작해야 합니다.
  • Component-level Client and Server Rendering
  • 경로가 로드 되면, Next.js와 React 런타임이 로드되는데 이는 캐시가 가능하고, 사이즈 예측이 가능합니다. 이 런타임은 프로젝트 크기가 커져도 변함이 없습니다. 또한 런타임은 비동기로 로드되고, 서버에 있던 HTML이 클라이언트에서 추가될 수 있습니다.
  • app directory는 React에서 새로나온 Server Components architecture를 지원합니다. Server and Client Components는 서버와 클라이언트에서 각자 최적의 상태로 작동합니다.
  • 형제 경로 간 이동할 때 Nextjs는 레이아웃과 페이지를 변경된 부분만 불러냅니다. 이를 통해 중복 렌더링과 패치를 막을 수 있습니다.
  • 추가적으로 라우터는 클라이언트 캐시에 서버 컴포넌트의 결과를 저장해둡니다. 이 캐시는 경로 세그먼트에 의해서 쪼개져서 모든 레벨에서 무효화를 허용하고, 렌더링 간에 일관성을 보장합니다. 따라서 이전에 가져온 세그먼트의 캐시를 사용해 성능을 더욱 향상 시킬 수 있습니다.
  • pages directory방식이 client-side routing을 사용하는 것과 달리, app directory방식은 Server Component와 서버에서 데이터 fetching을 통한 server-centric routing 방식을 사용합니다. server-centric-routing은 클라이언트가 경로 맵을 다운받을 필요가 없으며, 서버에서 해당 로직을 처리할 수 있습니다. 이러한 최적화는 많은 경로를 가진 프로그램일수록 더욱 좋습니다.
  • 위에서 살펴본 파일들에더해서 추가로 여러 파일들을 폴더 속에 포함 시킬 수 있습니다. 예시로 styleshhets, tests, components등등이 있습니다.
  • 이를 폴더들을 첨가한다면 아래와 같이 나타납니다.
  • 위에서 살펴본 파일들의 계층 구조를 설명합니다.
  • File Conventions
  • Folders : 폴더들은 경로를 규정하는데 사용됩니다. pages.js가 포함된 root 폴더에서 leaf폴더까지 계층 구조를 가지고, 이를 통해 single path를 만들어냅니다.
  • 기본적으로 app 은 React Server Components입니다. 이건 성능적으로 좋고, 쉽게 선택할 수 있지만, Client Components도 사용해야 합니다.
  • 새로운 router 방식은 app으로 명명되었습니다. app directory는 pages directory가 남아있는 과정에서 실험적으로 채택되었습니다. 이 방식을 통해 일부 router를 새로운 방식으로 동작하도록 하고, 나머지는 이전 동작 방식을 유지할 수 있습니다.
  • 자세히 살펴 보면 아래와 같습니다. (생략한 항목들이 있으니, 시간이 되신다면 원문을 읽어보시길 추천합니다. 😊)
  • export default function Page() { return ( <h1> Hello, Next.js! </h1> ) }
  • app/을 통해서 navigation 전반에서 상태를 유지하고, 리렌더링을 방지하고, 고급 라우팅 패턴을 사용할 수 있습니다. 또한 레이아웃을 중첩 할 수 있고, 컴포넌트, 테스트 및 스타일과 같은 코드들을 어플리케이션 코드에 같은 곳에 배치할 수 있습니다.
  • app directory는 현재 베타 버전이고, PR에는 추천하지 않습니다. 그리고 아직 pages directory는 next/image와 next/link 등 기존의 안정된 기능들과 함께 사용할 수 있습니다.
Comments