학습 문서/api reference/file conventions

template.js#

학습 목표#

  • 상태를 보존하는 layout과 매번 새 인스턴스를 만드는 template을 구분한다.
  • template이 필요한 reset·effect·fallback 시나리오를 판단한다.

핵심 개념 및 설명#

템플릿 파일은 레이아웃이나 페이지를 래핑한다는 점에서 레이아웃과 유사하다. 여러 경로에 걸쳐 유지되고 상태를 유지하는 레이아웃과 달리 템플릿에는 고유한 키가 제공된다. 즉, 하위 Client Component가 탐색 시 상태를 재설정한다.

다음과 같은 경우에 유용하다.

  • 탐색 시 useEffect를 다시 동기화한다.
  • 탐색 시 하위 Client Component의 상태를 재설정한다. 예를 들어 입력 필드이다.
  • 기본 프레임워크 동작을 변경한다. 예를 들어 레이아웃 내부의 Suspense 경계는 첫 번째 로드 시에만 대체를 표시하는 반면 템플릿은 모든 탐색에 이를 표시한다.

<a id="convention"></a>

규칙#

템플릿은 template.js 파일에서 기본 React 컴포넌트를 내보내 정의할 수 있다. 컴포넌트는 children prop을 허용해야 한다.

template.js 특수 파일
template.js 특수 파일
app/template.tsxtsx
export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}
app/template.jsjsx
export default function Template({ children }) {
  return <div>{children}</div>
}

중첩 측면에서 template.js는 레이아웃과 해당 하위 항목 사이에 렌더링된다. 다음은 단순화된 출력이다.

Outputjsx

<Layout>

<Template key={routeParam}>{children}</Template></Layout>

Outputjsx

컴포넌트 계층 구조에서 template.jslayout.jserror.js 사이를 렌더링한다.error.js,loading.js,not-found.jspage.js를 래핑하지만 동일한 세그먼트에서 layout.js를 래핑하지 않는다.

<a id="props"></a>

prop#

<a id="children-required"></a>

children(필수)#

템플릿은 children prop을 허용한다.

Outputjsx

<Layout>

<Template key={routeParam}>{children}</Template></Layout>

Outputjsx

<a id="behavior"></a>

동작#

  • Server Component: 기본적으로 템플릿은 Server Component이다.
  • 탐색 포함: 템플릿은 자체 세그먼트 수준에 대한 고유 키를 받는다. 해당 세그먼트(다이나믹 params 포함)가 변경되면 다시 마운트된다. 더 깊은 세그먼트 내의 탐색은 더 높은 수준의 템플릿을 다시 마운트하지 않는다. 검색 매개변수는 다시 마운트를 트리거하지 않는다.
  • 상태 재설정: 템플릿 내부의 모든 Client Component는 탐색 시 상태를 재설정한다.
  • 효과 재실행:useEffect와 같은 효과는 컴포넌트가 다시 마운트될 때 다시 동기화된다.
  • DOM 재설정: 템플릿 내부의 DOM 요소가 완전히 다시 생성된다.

<a id="templates-during-navigation-and-remounting"></a>

탐색 및 다시 마운트 중 템플릿#

이 섹션에서는 탐색 중에 템플릿이 작동하는 방식을 보여준다. 각 경로 변경 시 다시 탑재되는 템플릿과 그 이유를 단계별로 보여준다.

이 프로젝트 트리를 사용하여:

text
app
├── about
│   ├── page.tsx
├── blog
│   ├── [slug]
│   │   └── page.tsx
│   ├── page.tsx
│   └── template.tsx
├── layout.tsx
├── page.tsx
└── template.tsx

/부터 시작하는 React 트리는 대략 다음과 같다.

참고: 예제에 표시된 key 값은 예시일 뿐이며 애플리케이션의 값은 다를 수 있다.
Outputjsx

<RootLayout>

<Template key="/"><Page /></Template></RootLayout>

Outputjsx

/about(첫 번째 세그먼트 변경)로 이동하면 루트 템플릿 키가 변경되고 다시 마운트된다.

Outputjsx

<RootLayout>

<Template key="/about"><AboutPage /></Template></RootLayout>

text

/blog(첫 번째 세그먼트 변경)로 이동하면 루트 템플릿 키가 변경되고 다시 마운트되고 블로그 수준 템플릿이 마운트된다.

Outputjsx

<RootLayout>

<Template key="/blog">

<Template key="/blog"><BlogIndexPage /></Template></Template></RootLayout>

text

동일한 첫 번째 세그먼트 내에서 /blog/first-post(하위 세그먼트 변경)로 이동하면 루트 템플릿 키는 변경되지 않지만 블로그 수준 템플릿 키는 변경되어 다시 마운트된다.

Outputjsx

<RootLayout>

<Template key="/blog">

<Template key="/blog/first-post"><BlogPostPage slug="first-post" /></Template></Template></RootLayout>

text

/blog/second-post(동일한 첫 번째 세그먼트, 다른 하위 세그먼트)로 이동하면 루트 템플릿 키는 변경되지 않지만 블로그 수준 템플릿 키는 변경되어 다시 마운트된다.

Outputjsx

<RootLayout>

<Template key="/blog">

<Template key="/blog/second-post"><BlogPostPage slug="second-post" /></Template></Template></RootLayout>

text

<a id="version-history"></a>

Version History#

버전변경 사항
v13.0.0template가 출시되었다.

예제 및 데모 설계#

  • Phase 2에서 같은 입력 폼을 layout과 template에 각각 두고 page 이동 뒤 값 보존 여부를 비교한다.
  • useEffect mount log와 Suspense fallback 횟수를 기록한다.

연습 문제#

  1. 내비게이션마다 Client Component state를 초기화하려면?
  • A. layout.js
  • B. template.js
  • C. default.js
정답 보기

정답: B. template은 child별 key로 새 인스턴스를 mount한다.

챕터 요약#

  • template은 구조상 layout과 비슷하지만 내비게이션 때 remount된다.
  • template 안의 state는 보존되지 않는다.
  • effect와 Suspense fallback이 다시 실행된다.
  • 기본 선택은 layout이며 명시적인 reset이 필요할 때 template을 쓴다.

이 문서의 실습 데모