Next.js 13 - 1. Routing - 1.1 Routing Fundamentals

Chaewon Kang·2023년 4월 19일
2

Routing Fundamentals (라우팅 기본)

Next.js 13은 리액트 서버 컴포넌트를 기반으로 구현된 새로운 App Router 을 제공하며, 레이아웃, 중첩 라우팅, 로딩 상태, 에러 핸들링 등을 지원합니다.
이 페이지는 새로운 라우팅 모델에 대한 기본 개념들을 소개할 것입니다.

Terminology (용어)

도큐멘테이션 전반에 걸쳐 다음과 같은 용어들을 보게 될 거에요.

  • Tree : 위계 구조를 시각화하기 위한 규칙입니다. 부모/자식 컴포넌트, 폴더 구조 등에서의 컴포넌트 트리를 예로 들 수 있습니다.
  • Subtree : 트리의 일부로, 새로운 루트 (첫 번째) 에서 시작하고, 잎사귀들 (마지막)로 끝납니다.
  • Root : 트리나 서브 트리의 첫번 째 노드로, 루트 레이아웃을 예로 들 수 있습니다.
  • Leaf : 자식 요소들이 없는 서브 트리의 노드들로, URL 경로의 마지막 부분을 예로 들 수 있습니다.

  • URL Segment : 슬래시를 기반으로 설정되는 URL 경로의 부분입니다.
  • URL Path : segment 들로 이루어진, 도메인 이후에 따라오는 URL의 부분입니다.

The app Directory (app 디렉토리)

새로운 App Router은 app 이라는 이름의 새 디렉토리 안에서 실행됩니다. app 디렉토리는 기존의 pages 디렉토리와 함께 점진적으로 적용될 수 있도록 되어 있습니다. 이는 기존의 pages 디렉토리가 가지고 있던 다른 라우트들을 유지하면서 어플리케이션의 몇몇 라우트들을 새롭게 동작할 수 있도록 하는 선택지를 제공합니다.

알아두면 좋은 것들: 디렉토리를 가로지르는 라우트들은 같은 URL 경로를 리졸브하면 안 됩니다. 이는 충돌을 방지하기 위해 빌드타임 에러를 일으킬 거에요.

기본적으로 app 디렉토리 안의 컴포넌트들은 리액트 서버 컴포넌트입니다. 이는 성능 최적화이고, 쉽게 서버 컴포넌트들을 적용할 수 있도록 돕습니다. 그러나 당연히 클라이언트 컴포넌트 또한 사용할 수 있습니다.

추천 : 만약 서버 컴포넌트를 처음 접한다면, 리액트 서버 컴포넌트 페이지를 참조하세요.

Folders and Files inside app (app 디렉토리 안의 폴더와 파일들)

app 디렉토리 안에서는,

  • 폴더 들은 루트를 정의하기 위해 사용됩니다. 하나의 루트는 중첩된 폴더들의 단일한 경로입니다. 이 루트는 루트 폴더의 위계 구조를 따라, page.js 파일을 포함한 가장 말단의 잎사귀 폴더 (leaf folder) 까지 내려갑니다.
  • 파일 들은 각각의 루트들에서 보여질 UI를 생성하기 위해 사용됩니다. 특수한 파일들 페이지를 참조하세요.

Route Segments (루트 세그먼트)

루트 안의 각각의 폴더들은 루트 세그먼트 (route segment)를 나타냅니다. 각각의 루트 세그먼트들은 URL 경로의 상응하는 세그먼트들에 맵핑됩니다.

Nested Routes (중첩 루트)

중첩 라우팅을 하기 위해서는, 다른 폴더 안에 폴더들을 중첩할 수 있습니다. 예를 들어, app 디렉토리 안에 두 개의 폴더를 중첩함으로써 새로운 /dashboard/settings 라우트를 생성할 수 있습니다.

/dashboard/settings 라우트는 세 개의 세그먼트로 구성됩니다:

  • / (루트 세그먼트)
  • dashboard (세그먼트)
  • settings (잎사귀 세그먼트)

File Conventions (파일 컨벤션)

Next.js는 중첩된 라우트들 안에서 특정한 행동들을 수행하는 UI 생성을 위한 특별한 파일 묶음을 제공합니다.

  • page.js : 라우트를 위한 단일한 UI를 생성하고, path를 공개적으로 접근할 수 있도록 만듭니다.
    - route.js : 루트를 위한 서버사이드 API 엔드포인트를 생성합니다.
  • layout.js : 한 세그먼트와 그 세그먼트의 자식 요소들을 위한 공유 UI를 생성합니다. 레이아웃은 페이지 또는 자식 세그먼트를 감싸게 됩니다.
    - template.js : 네비게이션에 마운트된 새로운 컴포넌트를 제외하고는 layout.js와 비슷합니다. 해당 경우가 아니면 layouts를 이용하면 됩니다.
  • loading.js : 한 세그먼트와 그 세그먼트의 자식 요소들에 사용되는 로딩 UI를 생성합니다. loading.js는 한 페이지 또는 자식 요소들을, 그들이 로드되는 동안 로딩 UI를 보여주면서 리액트 서스펜스 바운더리 내에서 감싸게 됩니다.
  • error.js : 한 세그먼트와 그 세그먼트의 자식 요소들에 사용되는 에러 UI를 생성합니다. error.js는 에러가 발생된 경우 에러를 표시하며 리액트 에러 바운더리 내에서 한 페이지 또는 자식 요소들을 감싸게 됩니다.
    - global-error.js : error.js와 비슷하지만, 루트의 layout.js에서 발생한 에러를 캐치하기 위해 사용됩니다.
  • not-found.js : 루트 세그먼트 안에서 notFound 함수가 발생할 때 또는 URL이 어떤 루트에도 매치되지 않을 때 보여질 UI를 생성합니다.

알아두면 좋은 것: .js, .jsx 또는 .tsx 파일 확장자 모두 이러한 파일 생성에 사용될 수 있습니다.

Component Hierarchy (컴포넌트 위계)

루트 세그먼트상의 특별한 파일들 안에 정의된 리액트 컴포넌트들은 특정 위계를 따릅니다.

  • layout.js
  • template.js
  • error.js (리액트 에러 바운더리)
  • loading.js (리액트 서스펜스 바운더리)
  • not-found.js (리액트 에러 바운더리)
  • page.js 또는 중첩된 layout.js

중첩 루트에서, 한 세그먼트의 컴포넌트들은 그 세그먼트의 부모 컴포넌트 안에서 중첩됩니다.

Colocation (함께 위치하기)

특별한 파일들에 더해, 폴더들 내에 여러 파일들을 함께 위치시킬 수 있는 옵션이 있습니다. 예를들어, 스타일 시트, 테스트, 컴포넌트 등 말이죠.

Server-Centric Routing with Client-side Navigation (클라이언트 사이드 네비게이션과 서버 중심적인 라우팅)

클라이언트 사이드 라우팅을 제공하는 pages 디렉토리와는 다르게, app 디렉토리 내의 새로운 라우터는 서버 컴포넌트와 서버 측 데이터 페칭을 위해 서버 중심적 라우팅을 사용합니다. 서버 중심적 라우팅을 통해, 클라이언트는 루트들을 찾기 위해 사용될 수 있는 서버 컴포넌트를 위한 중복된 리퀘스트나 라우트 맵을 다운로드 할 필요가 없습니다. 이러한 최적화는 모든 애플리케이션에서 유용하지만, 많은 루트들을 가지고 있는 애플리케이션에서 특히 유용합니다.
라우팅 자체는 서버 중심적이지만, 라우터는 Link 컴포넌트를 통해 클라이언트 사이드 네비게이션을 사용할 수 있습니다. 이는 Single Page Application의 행동 양식과 닮았죠. 즉 유저가 새로운 루트를 네비게이팅 할 때, 브라우저는 페이지를 다시 로드하지 않습니다. 대신에, URL이 업데이트되고, Next.js는 변화한 세그먼트들만을 렌더링합니다.
그리고 유저가 애플리케이션을 이리저리 탐험할 때, 라우터는 리액트 서버 컴포넌트의 페이로드 결과값을 인-메모리 클라이언트 사이드 캐시에 저장하게 됩니다. 해당 캐시는 어떤 레벨에서든 무효화를 가능하게 하는 라우트 세그먼트에 의해 분할고, 동시적인 렌더들 사이에서 일관성을 유지할 수 있게 해 줍니다. 이는 어떠한 특정 상황들에서, 이전에 페치된 세그먼트의 캐시가 재사용될 수 있음을 뜻하며, 이는 퍼포먼스를 향상시킵니다.
Link 컴포넌트 사용 방법을 배우고 싶다면 Linking and Navigating 페이지를 참조하세요.

Partial Rendering (부분적인 렌더링)

형제 루트들 사이에서 네비게이팅을 할 때, (예를 들면 아래 이미지의 /dashboard/settings/dashboard/analytics) Next.js는 레이아웃들과 루트 안에서 변화한 페이지들만을 가져와서 렌더합니다. Next.js는 subtree 안에 위치한 세그먼트 상위의 것들은 다시 가져오거나 다시 렌더하지 않습니다. 이는 하나의 레이아웃을 공유하는 루트들 안에서, 유저가 형제 루트들 사이를 탐방할 때 레이아웃은 보존됨을 뜻합니다.

부분적인 렌더링이 없다면, 각각의 네비게이션은 서버에서 전체 페이지를 리렌더링 하게 됩니다. 업데이트되는 세그먼트만 렌더링하는 것은 전송되는 데이터의 양을 줄여 주고, 실행 시간을 단축시키며, 더 향상된 퍼포먼스를 이끌어냅니다.

Advanced Routing Patterns (향상된 라우팅 패턴)

좀 더 나중에는 Next.js 라우터는 더 향상된 라우팅 패턴을 도입하기 위해 몇 가지 컨벤션들을 제공할 예정입니다.

  • Parallel Routes (병렬 라우트) : 하나의 뷰 안에서 동시에 독립적으로 탐방할 수 있는 두 개 이상의 페이지들을 가능하게 합니다. 대시보드와 같이, 각각의 서브 네비게이션들이 있는 라우트들을 이용해 스플릿 뷰를 만들어낼 수 있습니다.
  • Intercepting Routes (인터셉팅 라우트) : 루트를 인터셉트 할 수 있게 하고, 다른 루트의 컨텍스트를 보여줄 수 있게 해 줍니다. 현재 페이지의 컨텍스트가 중요할 경우 이를 유지하기 위해 사용할 수 있습니다. 예를 들어 피드에서 사진을 확대하거나, 하나의 태스크를 편집하는 동시에 모든 태스크를 보고 싶을 때 이용할 수 있습니다.
  • Conditional Routes (조건부 라우트) : 조건을 기반으로 렌더를 처리할 수 있게 해 줍니다. 예를 들어 유저가 로그인을 한 경우에만 어떤 페이지를 보여줄 경우에 이용할 수 있습니다.
    이러한 패턴과 규약들은 당신의 Next.js 애플리케이션에서 더 풍부하고 복잡한 UI를 빌드할 수 있도록 해 줍니다.
profile
문학적 상상력과 기술적 가능성

0개의 댓글