Next.js 13은 리액트 서버 컴포넌트를 기반으로 구현된 새로운 App Router 을 제공하며, 레이아웃, 중첩 라우팅, 로딩 상태, 에러 핸들링 등을 지원합니다.
이 페이지는 새로운 라우팅 모델에 대한 기본 개념들을 소개할 것입니다.
도큐멘테이션 전반에 걸쳐 다음과 같은 용어들을 보게 될 거에요.
app
Directory (app
디렉토리)새로운 App Router은 app
이라는 이름의 새 디렉토리 안에서 실행됩니다. app
디렉토리는 기존의 pages
디렉토리와 함께 점진적으로 적용될 수 있도록 되어 있습니다. 이는 기존의 pages
디렉토리가 가지고 있던 다른 라우트들을 유지하면서 어플리케이션의 몇몇 라우트들을 새롭게 동작할 수 있도록 하는 선택지를 제공합니다.
알아두면 좋은 것들: 디렉토리를 가로지르는 라우트들은 같은 URL 경로를 리졸브하면 안 됩니다. 이는 충돌을 방지하기 위해 빌드타임 에러를 일으킬 거에요.
기본적으로 app
디렉토리 안의 컴포넌트들은 리액트 서버 컴포넌트입니다. 이는 성능 최적화이고, 쉽게 서버 컴포넌트들을 적용할 수 있도록 돕습니다. 그러나 당연히 클라이언트 컴포넌트 또한 사용할 수 있습니다.
추천 : 만약 서버 컴포넌트를 처음 접한다면, 리액트 서버 컴포넌트 페이지를 참조하세요.
app
(app
디렉토리 안의 폴더와 파일들)app
디렉토리 안에서는,
page.js
파일을 포함한 가장 말단의 잎사귀 폴더 (leaf folder) 까지 내려갑니다.루트 안의 각각의 폴더들은 루트 세그먼트 (route segment)를 나타냅니다. 각각의 루트 세그먼트들은 URL 경로의 상응하는 세그먼트들에 맵핑됩니다.
중첩 라우팅을 하기 위해서는, 다른 폴더 안에 폴더들을 중첩할 수 있습니다. 예를 들어, app
디렉토리 안에 두 개의 폴더를 중첩함으로써 새로운 /dashboard/settings
라우트를 생성할 수 있습니다.
/dashboard/settings
라우트는 세 개의 세그먼트로 구성됩니다:
/
(루트 세그먼트)dashboard
(세그먼트)settings
(잎사귀 세그먼트)Next.js는 중첩된 라우트들 안에서 특정한 행동들을 수행하는 UI 생성을 위한 특별한 파일 묶음을 제공합니다.
layout.js
와 비슷합니다. 해당 경우가 아니면 layouts를 이용하면 됩니다.loading.js
는 한 페이지 또는 자식 요소들을, 그들이 로드되는 동안 로딩 UI를 보여주면서 리액트 서스펜스 바운더리 내에서 감싸게 됩니다. error.js
는 에러가 발생된 경우 에러를 표시하며 리액트 에러 바운더리 내에서 한 페이지 또는 자식 요소들을 감싸게 됩니다.error.js
와 비슷하지만, 루트의 layout.js
에서 발생한 에러를 캐치하기 위해 사용됩니다.notFound
함수가 발생할 때 또는 URL이 어떤 루트에도 매치되지 않을 때 보여질 UI를 생성합니다.알아두면 좋은 것:
.js
,.jsx
또는.tsx
파일 확장자 모두 이러한 파일 생성에 사용될 수 있습니다.
루트 세그먼트상의 특별한 파일들 안에 정의된 리액트 컴포넌트들은 특정 위계를 따릅니다.
layout.js
template.js
error.js
(리액트 에러 바운더리)loading.js
(리액트 서스펜스 바운더리)not-found.js
(리액트 에러 바운더리)page.js
또는 중첩된 layout.js
중첩 루트에서, 한 세그먼트의 컴포넌트들은 그 세그먼트의 부모 컴포넌트 안에서 중첩됩니다.
특별한 파일들에 더해, 폴더들 내에 여러 파일들을 함께 위치시킬 수 있는 옵션이 있습니다. 예를들어, 스타일 시트, 테스트, 컴포넌트 등 말이죠.
클라이언트 사이드 라우팅을 제공하는 pages
디렉토리와는 다르게, app
디렉토리 내의 새로운 라우터는 서버 컴포넌트와 서버 측 데이터 페칭을 위해 서버 중심적 라우팅을 사용합니다. 서버 중심적 라우팅을 통해, 클라이언트는 루트들을 찾기 위해 사용될 수 있는 서버 컴포넌트를 위한 중복된 리퀘스트나 라우트 맵을 다운로드 할 필요가 없습니다. 이러한 최적화는 모든 애플리케이션에서 유용하지만, 많은 루트들을 가지고 있는 애플리케이션에서 특히 유용합니다.
라우팅 자체는 서버 중심적이지만, 라우터는 Link 컴포넌트를 통해 클라이언트 사이드 네비게이션을 사용할 수 있습니다. 이는 Single Page Application의 행동 양식과 닮았죠. 즉 유저가 새로운 루트를 네비게이팅 할 때, 브라우저는 페이지를 다시 로드하지 않습니다. 대신에, URL이 업데이트되고, Next.js는 변화한 세그먼트들만을 렌더링합니다.
그리고 유저가 애플리케이션을 이리저리 탐험할 때, 라우터는 리액트 서버 컴포넌트의 페이로드 결과값을 인-메모리 클라이언트 사이드 캐시에 저장하게 됩니다. 해당 캐시는 어떤 레벨에서든 무효화를 가능하게 하는 라우트 세그먼트에 의해 분할고, 동시적인 렌더들 사이에서 일관성을 유지할 수 있게 해 줍니다. 이는 어떠한 특정 상황들에서, 이전에 페치된 세그먼트의 캐시가 재사용될 수 있음을 뜻하며, 이는 퍼포먼스를 향상시킵니다.
Link 컴포넌트 사용 방법을 배우고 싶다면 Linking and Navigating 페이지를 참조하세요.
형제 루트들 사이에서 네비게이팅을 할 때, (예를 들면 아래 이미지의 /dashboard/settings
와 /dashboard/analytics
) Next.js는 레이아웃들과 루트 안에서 변화한 페이지들만을 가져와서 렌더합니다. Next.js는 subtree 안에 위치한 세그먼트 상위의 것들은 다시 가져오거나 다시 렌더하지 않습니다. 이는 하나의 레이아웃을 공유하는 루트들 안에서, 유저가 형제 루트들 사이를 탐방할 때 레이아웃은 보존됨을 뜻합니다.
부분적인 렌더링이 없다면, 각각의 네비게이션은 서버에서 전체 페이지를 리렌더링 하게 됩니다. 업데이트되는 세그먼트만 렌더링하는 것은 전송되는 데이터의 양을 줄여 주고, 실행 시간을 단축시키며, 더 향상된 퍼포먼스를 이끌어냅니다.
좀 더 나중에는 Next.js 라우터는 더 향상된 라우팅 패턴을 도입하기 위해 몇 가지 컨벤션들을 제공할 예정입니다.