IT/DEV

NEXT JS 공식문서

황하프 2024. 2. 3. 17:25
728x90
반응형
SMALL

NEXTJS 14버전을 기준으로 a-z까지 하루만에 공식문서 회독 컨텐츠 입니다.

모든 내용을 기록하지 않습니다. 하이라이트를 개인적으로 선정하여 기록하겠습니다.


 

NEXT JS?
풀스택 웹 애플리케이션을 구축하기 위한 React 프레임워크입니다.
React 컴포넌트를 사용하여 사용자 인터페이스를 구축하고 Next.js는 번들링, 컴파일 등과 같이 React에 필요한 도구를 추상화하고 자동으로 구성하며 최적화를 구현합니다.

Main Features

라우팅 레이아웃, 중첩 라우팅, 로딩 상태, 오류 처리 등을 지원하는 서버 구성 요소 위에 구축된 파일 시스템 기반 라우터입니다.
렌더링 클라이언트 및 서버 구성 요소를 사용한 클라이언트 측 및 서버 측 렌더링. Next.js를 사용하여 서버에서 정적 및 동적 렌더링으로 더욱 최적화되었습니다. Edge 및 Node.js 런타임에서 스트리밍합니다
데이터 패치 서버 구성 요소의 async/await를 사용하여 데이터 가져오기를 단순화하고 fetch요청의 메모라이징, 데이터 캐싱 및 재검증을 위한 확장된 API를 제공합니다.

 

Install

```npx create-next-app@latest```

 

파일규칙

layout 세그먼트 및 해당 하위 항목에 대한 공유 UI
page 경로의 고유한 UI 및 경로에 공개적으로 액세스 가능 -> index
loading 세그먼트 및 해당 하위 항목에 대한 UI 로드 중
not-found 세그먼트 및 해당 하위 항목에 대한 UI를 찾을 수 없습니다.
error 세그먼트 및 해당 하위 항목에 대한 오류 UI
global-error 전역 오류 UI
route 서버 측 API 엔드포인트
template 전문적으로 다시 렌더링된 레이아웃 UI
default 병렬 경로 에 대한 대체 UI

 

중첩 경로에서는 세그먼트의 구성 요소가 상위 세그먼트의 구성 요소 내에 중첩됩니다 .

경로생성

Next.js는 폴더를 사용하여 경로를 정의하는 파일 시스템 기반 라우터를 사용합니다 .

 

각 폴더는 URL 세그먼트 에 매핑되는 경로 세그먼트를 나타냅니다 . 중첩된 경로를 만들려면 폴더를 서로 중첩하면 됩니다.

페이지

컴포넌트를 내보내 페이지를 정의할 수 있습니다.해당 경로에 공개적으로 액세스할 수 있도록 합니다.

// `app/page.tsx` is the UI for the `/` URL
export default function Page() {
  return <h1>Hello, Home page!</h1>
}

 

+ 페이지는 기본적으로 서버 구성 요소 이지만 클라이언트 구성 요소로 설정할 수 있습니다 .
페이지는 데이터를 가져올 수 있습니다.

 

레이아웃

레이아웃은 여러 페이지에서 공유되는 UI입니다. 레이아웃은 중첩 될 수도 있습니다 .

default 파일 에서 React 컴포넌트를 내보내 레이아웃을 정의할 수 있습니다.

export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>
 
      {children}
    </section>
  )
}

+ 최상위 레이아웃을 루트 레이아웃 이라고 합니다.애플리케이션의 모든 페이지에서 공유됩니다. 루트 레이아웃에는 html및 body태그가 포함되어야 합니다.
모든 경로 세그먼트는 선택적으로 자체 레이아웃을 정의할 수 있습니다 .이러한 레이아웃은 해당 세그먼트의 모든 페이지에서 공유됩니다. 경로의 레이아웃은 기본적으로 중첩 됩니다.
각 상위 레이아웃은 React childrenprop을 사용하여 그 아래의 하위 레이아웃을 래핑합니다.
경로 그룹을 사용하여 공유 레이아웃 안팎에서 특정 경로 세그먼트를 선택할 수 있습니다.
레이아웃은 기본적으로 서버 구성요소 이지만 클라이언트 구성요소 로 설정할 수 있습니다 .
레이아웃은 데이터를 가져올 수 있습니다.
상위 레이아웃과 해당 하위 레이아웃 간에 데이터를 전달하는 것은 불가능합니다.
레이아웃은 자체 아래의 경로 세그먼트에 접근할 수 없습니다. 모든 경로 세그먼트에 액세스하려면 클라이언트 구성 요소에서 useSelectedLayoutSegment또는를 사용할 수 있습니다 .useSelectedLayoutSegments

 

루트 레이아웃(필수)

루트 레이아웃은 디렉터리의 최상위 수준에서 정의되며 app모든 경로에 적용됩니다. 이 레이아웃을 사용하면 서버에서 반환된 초기 HTML을 수정할 수 있습니다.

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

+ 디렉터리 app에는 루트 레이아웃이 포함되어야 합니다.
Next.js는 루트 레이아웃을 자동으로 생성하지 않으므로 루트 레이아웃을 정의 <html>과 태그를 지정해야 합니다. 

 

중첩 레이아웃

폴더(예: app/dashboard/layout.js) 내부에 정의된 레이아웃은 특정 경로 세그먼트(예 gmarket.com/dashboard: )에 적용되고 해당 세그먼트가 활성화되면 렌더링됩니다. 기본적으로 파일 계층 구조의 레이아웃은 중첩 되어 있습니다 . 즉, childrenprop을 통해 하위 레이아웃을 래핑합니다.

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}

//루트 레이아웃에만 <html>및 <body>태그가 포함될 수 있습니다.

 

<Link>

HTML a 태그를 확장하여 경로 간 프리패치 및 클라이언트 측 탐색을 내장 컴포넌트 입니다.

'use client'
 
import { usePathname } from 'next/navigation'
import Link from 'next/link'
 
export function Links() {
  const pathname = usePathname()
 
  return (
    <nav>
      <ul>
        <li>
          <Link
            className={`link ${pathname === '/about' ? 'active' : ''}`}
            href="/about"
          >
            About
          </Link>
        </li>
      </ul>
    </nav>
  )
}

+ 앱 라우터의 기본 동작은 이동 경로의 맨 위로 스크롤하거나 앞뒤 탐색을 위해 스크롤 위치를 유지하는 것입니다. 탐색 시 특정 항목으로 스크롤하려면 idURL에 #해시 링크를 추가하거나 해시 링크를 hrefprop에 전달할 수 있습니다.

<Link href="/dashboard#settings">Settings</Link>
 
// Output
<a href="/dashboard#settings">Settings</a>

//스크롤 비활성화도 가능
// next/link
<Link href="/dashboard" scroll={false}>
  Dashboard
</Link>
// useRouter
import { useRouter } from 'next/navigation'
 
const router = useRouter()
 
router.push('/dashboard', { scroll: false })

 

redirect

서버 컴포넌트 의 경우 대신 해당 기능을 사용하십시오.

import { redirect } from 'next/navigation'
 
async function fetchTeam(id: string) {
  const res = await fetch('https://...')
  if (!res.ok) return undefined
  return res.json()
}
 
export default async function Profile({ params }: : { params: { id: string }) {
  const team = await fetchTeam(params.id)
  if (!team) {
    redirect('/login')
  }
 
  // ...
}

+ redirect기본적으로 307(임시 리디렉션) 상태 코드를 반환합니다. 서버 작업에서 사용될 경우 POST 요청의 결과로 성공 페이지로 리디렉션하는 데 일반적으로 사용되는 303(기타 참조)을 반환합니다. redirect또한 절대 URL을 허용하며 외부 링크로 리디렉션하는 데 사용할 수 있습니다.

 

Using the native History API

window.history.pushState, window.history.replaceState를 사용해 페이지를 다시 로드하지 않고
브라우저의 히스토리 스택을 업데이트
window.history.pushState:

window.history.pushState(null, '', `?${params.toString()}`)
브라우저의 히스토리 스택에 새 항목을 추가합니다.
사용자는 이전 상태로 돌아갈 수 있습니다.

window.history.replaceState:

window.history.replaceState(null, '', newPath);
   
브라우저 히스토리 스택의 현재 항목을 바꾸는 데 사용합니다.
사용자는 이전 상태로 다시 이동할 수 없습니다.

 

라우팅 및 탐색 작동 방식

앱 라우터는 라우팅 및 탐색을 위해 하이브리드 접근 방식을 사용합니다. 서버에서 애플리케이션 코드는 경로 세그먼트별로 자동으로 코드 스플리팅 됩니다. 그리고 클라이언트에서 Next.js는 경로 세그먼트를 미리 가져 오고 캐시합니다 .즉, 사용자가 새 경로로 이동할 때 브라우저는 페이지를 다시 로드하지 않고 변경된 경로 세그먼트만 다시 렌더링하여 탐색 경험과 성능을 향상시킵니다.

 

코드 스플리팅

코드 스플리팅을 사용하면 애플리케이션 코드를 더 작은 번들로 분할하여 브라우저에서 다운로드하고 실행할 수 있습니다. 이를 통해 전송되는 데이터의 양과 각 요청의 실행 시간이 줄어들어 성능이 향상됩니다. 서버 구성 요소를 사용하면 애플리케이션 코드가 경로 세그먼트별로 자동으로 코드 분할될 수 있습니다. 즉, 현재 경로에 필요한 코드만 내비게이션에 로드됩니다.

 

프리페치

프리페치는 사용자가 경로를 방문하기 전에 백그라운드에서 경로를 미리 로드하는 방법입니다. Next.js에서 경로를 미리 가져오는 방법에는 두 가지가 있습니다. 1.<Link>구성 요소 : 경로가 사용자의 뷰포트에 표시되면 자동으로 미리 가져옵니다. 프리페치는 페이지가 처음 로드될 때 또는 스크롤을 통해 표시될 때 발생합니다. 2.router.prefetch(): useRouter후크를 사용하여 프로그래밍 방식으로 경로를 미리 가져올 수 있습니다. prefetchprop으로 프리페칭을 비활성화할 수 있습니다 false. 

+ 프리페칭은 개발 중에는 활성화되지 않고 프로덕션에서만 활성화됩니다.

 

캐싱

Next.js에는 라우터 캐시(Router Cache) 라는 메모리 내 클라이언트 측 캐시가 있습니다 . 사용자가 앱을 탐색할 때 미리 가져온 경로 세그먼트와 방문한 경로의 React Server 구성 요소 페이로드가 캐시에 저장됩니다. 이는 탐색 시 서버에 새로운 요청을 하는 대신 캐시를 최대한 재사용하여 요청 수와 전송되는 데이터 수를 줄여 성능을 향상한다는 의미입니다.

 

부분 렌더링

리랜더링시 공유되는 세그먼트를 제외하고 변경되는 부분만 렌더링 됩니다.
예를 들어 두 형제 경로 및 사이를 탐색하는 경우 /dashboard/settings및 /dashboard/analytics페이지 settings가 analytics렌더링되고 공유 dashboard레이아웃이 유지됩니다.

부분 렌더링이 없으면 탐색할 때마다 클라이언트에서 전체 페이지가 다시 렌더링됩니다. 변경된 세그먼트만 렌더링하면 전송되는 데이터의 양과 실행 시간이 줄어들어 성능이 향상됩니다.

즉시 로딩 상태

페이지 탐색 시 즉시 표시되는 대체 UI입니다.

서스펜스를 이용한 스트리밍

- 스트리밍이란 무엇입니까?

SSR을 사용하면 사용자가 페이지를 보고 상호 작용하기 전에 완료해야 하는 일련의 단계가 있습니다.

  1. 먼저, 특정 페이지의 모든 데이터를 서버에서 가져옵니다.
  2. 그런 다음 서버는 페이지의 HTML을 렌더링합니다.
  3. 페이지의 HTML, CSS 및 JavaScript가 클라이언트로 전송됩니다.
  4. 정적인 사용자 인터페이스는 생성된 HTML 및 CSS를 사용하여 표시됩니다.
  5. 마지막으로 React는 하이드레이트를 합니다. 사용자 인터페이스를 동적으로 만듭니다.

이러한 단계는 순차적입니다. 즉, 모든 데이터를 가져온 후에만 서버가 페이지의 HTML을 렌더링할 수 있습니다. 그리고 클라이언트에서 React는 페이지의 모든 구성 요소에 대한 코드가 다운로드된 후에만 UI를 하이드레이션할 수 있습니다.

그러나 페이지가 사용자에게 표시되기 전에 서버에서 모든 데이터 가져오기가 완료되어야 하므로 여전히 속도가 느릴 수 있습니다.

스트리밍을 사용하면 페이지의 HTML을 더 작은 청크로 나누고 점진적으로 해당 청크를 서버에서 클라이언트로 보낼 수 있습니다.

 

이를 통해 UI가 렌더링되기 전에 모든 데이터가 로드될 때까지 기다리지 않고 페이지의 일부를 더 빨리 표시할 수 있습니다.

스트리밍은 각 컴포넌트가 하나의 덩어리로 간주될 수 있기 때문에 React의 컴포넌트 모델과 잘 작동합니다. 우선 순위가 더 높거나(예: 제품 정보) 데이터에 의존하지 않는 구성 요소(예: 레이아웃)가 먼저 전송될 수 있으며 React는 더 일찍 하이드레이트를 시작할 수 있습니다. 

 

스트리밍은 TTFB(Time To First Byte)를 줄일 수 있으므로 긴 데이터 요청으로 인해 페이지 렌더링이 차단되는 것을 방지하려는 경우 특히 유용합니다.첫 번째 콘텐츠가 포함된 페인트(FCP). 또한 TTI(Time to Interactive)를 개선하는 데 도움이 됩니다.특히 느린 장치에서는 더욱 그렇습니다.

 

import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
 
export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Loading feed...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense fallback={<p>Loading weather...</p>}>
        <Weather />
      </Suspense>
    </section>
  )
}

Suspense를 사용하면 다음과 같은 이점을 얻을 수 있습니다.
스트리밍 서버 렌더링 - 서버에서 클라이언트로 HTML을 점진적으로 렌더링합니다.
선택적 하이드레이트 - React는 사용자 상호 작용을 기반으로 어떤 구성 요소를 먼저 동적으로 만들 것인지 우선 순위를 정합니다.

 

오류 처리

error.js 에서 예기치 않은 런타임 오류를 적절하게 처리할 수 있습니다 . React Error Boundary 에서 경로 세그먼트와 중첩된 하위 항목을 자동으로 래핑합니다. 

'use client' // Error components must be Client Components
 
import { useEffect } from 'react'
 
export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // Log the error to an error reporting service
    console.error(error)
  }, [error])
 
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          // Attempt to recover by trying to re-render the segment
          () => reset()
        }
      >
        Try again
      </button>
    </div>
  )
}

error.js는 React Error Boundary를 자동으로 생성합니다.

오류 경계 내에서 오류가 발생하면 오류가 포함되고 대체 구성요소가 렌더링 됩니다 . 

 

루트 레이아웃의 오류 처리

global-error.js이 애플리케이션을 감싸고 해당 폴백 구성 요소가 활성화되면 루트 레이아웃을 대체합니다. 이 때문에 자신의 태그 와 태그를 정의 해야 한다는 점에 유의하는 것이 중요합니다 . 루트 구성 요소는 일반적으로 덜 동적이며 다른 error.js경계는 대부분의 오류를 포착하므로 자주 트리거될 가능성이 없습니다.

'use client'
 
export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  )
}

 

서버 오류 처리

Error서버 구성 요소 내부에서 오류가 발생하면 Next.js는 객체(프로덕션에서 민감한 오류 정보가 제거된)를 가장 가까운 error.js파일에 prop으로 전달합니다. message에는 오류에 대한 일반 메시지가 포함되어 있으며 digest서버 측 로그에서 해당 오류를 일치시키는 데 사용할 수 있는 자동으로 생성된 오류 해시가 포함되어 있습니다. 개발 중에 Error클라이언트에 전달된 개체는 직렬화되고 message보다 쉬운 디버깅을 위해 원래 오류가 포함됩니다.

경로 그룹

폴더가 경로의 URL 경로에 포함되지 않도록 폴더를 경로 그룹 으로 표시할 수 있습니다. 이를 통해 URL 경로 구조에 영향을 주지 않고 경로 세그먼트와 프로젝트 파일을 논리 그룹으로 구성할 수 있습니다.

공통 레이아웃
개별 레이아웃

개인 폴더

개인 폴더는 폴더 앞에 밑줄을 붙여 생성할 수 있습니다._folderName 이는 폴더가 비공개 구현 세부 사항이므로 라우팅 시스템에서 고려해서는 안 되므로 폴더와 모든 하위 폴더를 라우팅에서 제외함을 나타냅니다.

동적 경로

정확한 세그먼트 이름을 미리 모르고 동적 데이터에서 경로를 생성

동적 세그먼트는 폴더 이름을 대괄호로 묶어 생성할 수 있습니다 [folderName]. 예를 들어, [id]또는 [slug].

동적 세그먼트는 특정 구성요소가 params에 prop 으로 전달됩니다.

예를 들어 블로그에는 블로그 게시물의 동적 세그먼트가 있는 app/blog/[slug]/page.js다음 경로가 포함될 수 있습니다.[slug]

export default function Page({ params }: { params: { slug: string } }) {
  return <div>My Post: {params.slug}</div>
}

 

app/blog/[slug]/page.js url:/blog/a 파람:{ slug: 'a' }
app/blog/[slug]/page.js url:/blog/b 파람:{ slug: 'b' }

 

정적 매개변수 생성

동적 경로 세그먼트를 generateStaticParams 와 함께 사용하여 빌드 시 경로를 정적으로 생성 할 수 있습니다.

export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  return posts.map((post) => ({
    slug: post.slug,
  }))
}

generateStaticParams요청을 사용하여 함수 내에서 콘텐츠를 가져오는 경우 fetch요청이 자동으로 메모 됩니다 . 이는 fetch여러 , 레이아웃 및 페이지에서 동일한 인수를 사용하는 요청이 generateStaticParams한 번만 이루어지므로 빌드 시간이 단축됨을 의미합니다.

 

포괄 세그먼트

대괄호 안에 줄임표를 추가하면 동적 세그먼트를 모든 후속 세그먼트 로 확장할 수 있습니다 

 

app/shop/[...slug]/page.js /shop/a { slug: ['a'] }
app/shop/[...slug]/page.js /shop/a/b { slug: ['a', 'b'] }
app/shop/[...slug]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }

 

선택적 포괄 세그먼트

이중 대괄호 안에 매개변수를 포함하여 포괄 세그먼트를 선택사항으로[[...folderName]] 만들 수 있습니다.

catch-all 세그먼트 와 선택적 catch-all 세그먼트 의 차이점은 선택 사항을 사용하면 매개변수가 없는 경로도 일치한다는 것입니다.

app/shop/[[...slug]]/page.js /shop {}
app/shop/[[...slug]]/page.js /shop/a { slug: ['a'] }
app/shop/[[...slug]]/page.js /shop/a/b { slug: ['a', 'b'] }
app/shop/[[...slug]]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }

 

병렬 경로

병렬 경로를 사용하면 동일한 레이아웃 내에서 하나 이상의 페이지를 동시에 또는 조건부로 렌더링할 수 있습니다.

슬롯은 경로 세그먼트가 아니며 URL 구조에 영향을 주지 않습니다. 예를 들어 의 경우 URL은 슬롯 이므로 URL이 됩니다

export default function Layout({
  children,
  team,
  analytics,
}: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {children}
      {team}
      {analytics}
    </>
  )
}

 

default.js

default.js초기 로드 또는 전체 페이지 다시 로드 중에 일치하지 않는 슬롯에 대한 대체 항목으로 렌더링할 파일을 정의할 수 있습니다 .

 

탭 그룹

layout 사용자가 독립적으로 슬롯을 탐색할 수 있도록 슬롯 내부에 를 추가할 수 있습니다 . 이는 탭을 생성하는 데 유용합니다.

import Link from 'next/link'
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <nav>
        <Link href="/dashboard/page-views">Page Views</Link>
        <Link href="/dashboard/visitors">Visitors</Link>
      </nav>
      <div>{children}</div>
    </>
  )
}

 

모달

평행 경로는 가로채기 경로 와 함께 사용하여 모달을 생성할 수 있습니다.  모달을 닫는 대신 페이지를 새로 고칠 때 컨텍스트를 유지합니다 . 이전 경로로 이동하지 않고 뒤로 탐색 시 모달을 닫습니다 . 앞으로 탐색 시 모달을 다시 엽니다 .

그런 다음 @auth슬롯 내부 default.js에 null. 이렇게 하면 모달이 활성화되지 않을 때 렌더링되지 않습니다.

슬롯 내부에서 폴더를 업데이트하여 경로를 @auth차단하세요.

// app/@auth/(.)login/page.tsx
import { Modal } from '@/app/ui/modal'
import { Login } from '@/app/ui/login'
 
export default function Page() {
  return (
    <Modal>
      <Login />
    </Modal>
  )
}

이제 Next.js 라우터를 활용하여 모달을 열고 닫을 수 있습니다. 이렇게 하면 모달이 열려 있을 때와 앞뒤로 탐색할 때 URL이 올바르게 업데이트됩니다. 모달을 열려면 @auth슬롯을 상위 레이아웃에 소품으로 전달하고 소품과 함께 렌더링합니다 children.

import Link from 'next/link'
 
export default function Layout({
  auth,
  children,
}: {
  auth: React.ReactNode
  children: React.ReactNode
}) {
  return (
    <>
      <nav>
        <Link href="/login">Open modal</Link>
      </nav>
      <div>{auth}</div>
      <div>{children}</div>
    </>
  )
}

사용자가 를 클릭하면 <Link>페이지로 이동하는 대신 모달이 열립니다 /login. 그러나 새로 고침 또는 초기 로드 시 다음으로 이동하면 /login사용자가 기본 로그인 페이지로 이동하게 됩니다.

router.back()구성 요소를 호출하거나 사용하여 모달을 닫을 수 있습니다 Link.

 

경로 차단

경로를 가로채면 현재 레이아웃 내 애플리케이션의 다른 부분에서 경로를 로드할 수 있습니다. 이 라우팅 패러다임은 사용자가 다른 컨텍스트로 전환하지 않고도 경로의 내용을 표시하려는 경우 유용할 수 있습니다. 예를 들어, 피드에서 사진을 클릭하면 피드에 오버레이되어 사진을 모달로 표시할 수 있습니다. 이 경우 Next.js는 /photo/123경로를 가로채서 URL을 마스크하고 이를 오버레이합니다 /feed.

경로 차단은 규칙을 사용하여 정의할 수 있는데 (..), 이는 상대 경로 규칙과 유사 ../하지만 세그먼트에 대한 것입니다.

당신이 사용할 수있는:

  • (.)동일한 수준 의 세그먼트를 일치시키려면
  • (..)한 수준 위의 세그먼트와 일치시키려면
  • (..)(..)두 수준 위의 세그먼트와 일치시키려면
  • (...)루트 app 디렉터리 의 세그먼트를 일치시키려면

예를 들어 디렉터리를 생성하여 세그먼트 photo내에서 세그먼트를 가로챌 수 있습니다 .feed(..)photo

가로채기 경로는 평행 경로 와 함께 사용하여 모달을 생성할 수 있습니다. 이를 통해 다음과 같은 모달 구축 시 일반적인 문제를 해결할 수 있습니다. URL을 통해 모달 콘텐츠를 공유 가능하게 만듭니다 . 모달을 닫는 대신 페이지를 새로 고칠 때 컨텍스트를 유지합니다 . 이전 경로로 이동하지 않고 뒤로 탐색 시 모달을 닫습니다 . 앞으로 탐색 시 모달을 다시 엽니다 . 사용자가 클라이언트 측 탐색을 사용하여 갤러리에서 사진 모달을 열거나 공유 가능한 URL에서 직접 사진 페이지로 이동할 수 있는 다음 UI 패턴을 고려해보세요.

 

위의 예에서 세그먼트에 대한 경로는 세그먼트 가 아니라 슬롯이므로 일치자를 photo사용할 수 있습니다 . 이는 파일 시스템 수준이 두 개 더 높음에도 불구하고 경로가 한 세그먼트 수준만 높다는 것을 의미합니다.(..)@modalphoto

 

라우트 핸들러

경로 핸들러를 사용하면 웹 요청을 사용하여 특정 경로에 대한 사용자 정의 요청 핸들러를 생성할 수 있습니다.

다음 HTTP 메소드GET, POST, PUT, PATCH, DELETE, HEAD및 가 지원됩니다 OPTIONS. 지원되지 않는 메서드가 호출되면 Next.js는 405 Method Not Allowed응답을 반환합니다.

 

캐싱

export async function GET() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    headers: {
      'Content-Type': 'application/json',
      'API-Key': process.env.DATA_API_KEY,
    },
  })
  const data = await res.json()
 
  return Response.json({ data })
}

//GET경로 핸들러는 객체 와 함께 메서드를 사용할 때 기본적으로 캐시됩니다 Response.

캐싱해제
Request메소드 와 함께 객체를 사용합니다 GET.
다른 HTTP 메서드를 사용합니다.
cookies-headers set
세그먼트 구성 옵션은 동적 모드를 수동으로 지정합니다.

 

 

캐시된 데이터 재검증

export async function GET() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    next: { revalidate: 60 }, // Revalidate every 60 seconds
  })
  const data = await res.json()
 
  return Response.json(data)
}

 

쿠키

cookies from 을 사용하여 쿠키를 읽거나 설정할 수 있습니다 next/headers. 이 서버 함수는 Route Handler에서 직접 호출되거나 다른 함수 내에 중첩될 수 있습니다. 또는 다음 Response을 사용하여 새 제품을 반환할 수 있습니다.

import { cookies } from 'next/headers'
 
export async function GET(request: Request) {
  const cookieStore = cookies()
  const token = cookieStore.get('token')
 
  return new Response('Hello, Next.js!', {
    status: 200,
    headers: { 'Set-Cookie': `token=${token.value}` },
  })
}

import { type NextRequest } from 'next/server'
 
export async function GET(request: NextRequest) {
  const token = request.cookies.get('token')
}

 

헤더 / URL 쿼리 매개변수 / 동적세그먼트 경로 / 폼데이터

import { headers } from 'next/headers'
 
export async function GET(request: Request) {
  const headersList = headers()
  const referer = headersList.get('referer')
 
  return new Response('Hello, Next.js!', {
    status: 200,
    headers: { referer: referer },
  })
}

import { type NextRequest } from 'next/server'
 
export async function GET(request: NextRequest) {
  const requestHeaders = new Headers(request.headers)
}

//동적 경로 세그먼트
export async function GET(
  request: Request,
  { params }: { params: { slug: string } }
) {
  const slug = params.slug // 'a', 'b', or 'c'
}

//URL 쿼리 매개변수
import { type NextRequest } from 'next/server'
 
export function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams
  const query = searchParams.get('query')
  // query is "hello" for /api/search?query=hello
}

// 요청 본문 양식 데이터
export async function POST(request: Request) {
  const formData = await request.formData()
  const name = formData.get('name')
  const email = formData.get('email')
  return Response.json({ name, email })
}

 

 

 

미들웨어

미들웨어를 사용하면 요청이 완료되기 전에 코드를 실행할 수 있습니다. 그런 다음 들어오는 요청에 따라 요청 또는 응답 헤더를 다시 작성, 리디렉션, 수정하거나 직접 응답하여 응답을 수정할 수 있습니다. 미들웨어는 캐시된 콘텐츠와 경로가 일치하기 전에 실행됩니다. 

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url))
}
 
// See "Matching Paths" below to learn more
export const config = {
  matcher: '/about/:path*',
}

 

일치하는 경로

프로젝트의 모든 경로 에 대해 미들웨어가 호출됩니다 . 실행 순서는 다음과 같습니다.

  1. headers~에서next.config.js
  2. redirects~에서next.config.js
  3. 미들웨어( rewrites, redirects등)
  4. beforeFiles( rewrites) 에서next.config.js
  5. 파일 시스템 경로( public/, _next/static/, pages/, app/등)
  6. afterFiles( rewrites) 에서next.config.js
  7. 동적 경로( /blog/[slug])
  8. fallback( rewrites) 에서next.config.js

 

728x90
반응형
LIST

'IT > DEV' 카테고리의 다른 글

RPC  (0) 2024.01.03