Загрузка...
Загрузка...
В Next.js App Router layouts и templates определяют общую структуру страниц. Layout оборачивает дочерние страницы и сохраняет свое состояние при навигации. Template делает то же самое, но пересоздается при каждом переходе.
Layout это компонент, который разделяется между несколькими страницами. При навигации между дочерними страницами layout не перемонтируется и сохраняет состояние:
// app/layout.tsx (корневой layout)
export default function RootLayout({
children
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<Header />
<main>{children}</main>
<Footer />
</body>
</html>
)
}
Корневой layout обязателен и должен содержать теги <html> и <body>.
Layouts могут быть вложенными. Каждый сегмент может иметь свой layout:
// app/docs/layout.tsx
export default function DocsLayout({
children
}: {
children: React.ReactNode
}) {
return (
<div className="flex">
<DocsSidebar />
<div className="flex-1">{children}</div>
</div>
)
}
Когда пользователь переходит между страницами документации на Hack Frontend, боковая навигация (sidebar) не перемонтируется. Это дает плавный UX.
Ключевое свойство layout: при навигации между дочерними страницами React не перемонтирует layout. Это значит:
'use client'
// app/problems/layout.tsx
import { useState } from 'react'
export default function ProblemsLayout({
children
}: {
children: React.ReactNode
}) {
const [filter, setFilter] = useState('all')
return (
<div>
<FilterBar value={filter} onChange={setFilter} />
{children}
</div>
)
}
Фильтр сохранится при навигации между /problems/1 и /problems/2.
Template работает как layout, но пересоздается при каждой навигации:
// app/docs/template.tsx
export default function DocsTemplate({
children
}: {
children: React.ReactNode
}) {
return <div>{children}</div>
}
| Layout | Template | |
|---|---|---|
| Перемонтирование | Нет | Да, при каждой навигации |
| Состояние (useState) | Сохраняется | Сбрасывается |
| useEffect | Не перезапускается | Запускается заново |
| DOM | Не пересоздается | Пересоздается |
Layout оборачивает остальные специальные файлы в определенном порядке:
layout.tsx
template.tsx
error.tsx (React Error Boundary)
loading.tsx (React Suspense)
not-found.tsx
page.tsx
Практический совет:
В большинстве случаев используй layout. Template нужен только когда требуется сбрасывать состояние или запускать эффекты при навигации.