webroad.online
  1. 1Веб
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Инструменты
  8. 8React
  9. 9Стейт-менеджмент
  10. 10Next.js
  11. 11Формы
  12. 12Данные и бэкенд
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Анимации
  16. 16Тестирование
  17. 17Архитектура
Next.js · Урок 2 из 12

Layout, состояния и навигация

Вложенные layout, loading/error/not-found, Link и useRouter.

Обновлено

Что такое layout

Layout — интерфейс, общий для нескольких страниц: шапка, сайдбар, подвал. Вы пишете его один раз, а страницы рендерятся на месте children.

// app/blog/layout.tsx
export default function BlogLayout({ children }: LayoutProps<'/blog'>) {
  return (
    <div className="grid grid-cols-[200px_1fr]">
      <BlogSidebar />
      {children}            {/* здесь появляется текущая страница */}
    </div>
  )
}

Самое важное свойство: при навигации между дочерними страницами layout не перемонтируется — его состояние (поле ввода, прокрутка сайдбара) сохраняется. Меняется только children.

Layout вкладываются

/blog/privet = app/layout.tsx → app/blog/layout.tsx → app/blog/[slug]/page.tsx.

Layout и template — различия

layout.tsx template.tsx
При навигации между детьми сохраняется, состояние остаётся перемонтируется, состояние сбрасывается
Когда почти всегда анимации появления, сброс формы на каждой странице

Состояния интерфейса как файлы

Next автоматически превращает специальные файлы в нужные React-компоненты:

Файл Становится Когда появляется
loading.tsx <Suspense fallback> вокруг страницы пока грузятся данные страницы
error.tsx error boundary ошибка, брошенная в сегменте
not-found.tsx страница 404 notFound() или несуществующий маршрут
global-error.tsx error boundary для корневого layout ошибки и в layout
'use client'      // error.tsx должен быть Client Component

export default function Error({ error, reset }: { error: Error; reset: () => void }) {
  return (
    <div>
      <p>Что-то пошло не так.</p>
      <button onClick={reset}>Попробовать снова</button>
    </div>
  )
}

Что такое клиентская навигация

С обычным <a href> браузер заново скачивает всю страницу. С <Link> Next получает только изменённое и обновляет страницу без перезагрузки — layout остаются, переход мгновенный.

import Link from 'next/link'
<Link href="/blog/privet">Читать</Link>

<Link> ещё и делает prefetch: когда ссылка появляется на экране, Next начинает загружать маршрут в фоне.

Способы навигации — и когда

Способ Где Когда
<Link href> где угодно по умолчанию — любая навигация по клику на ссылку
useRouter().push('/x') Client Component после действия: отправка формы, условная логика
router.refresh() Client Component перезапрашивает серверные данные текущей страницы
redirect('/login') Server Component, Server Action пользователю сюда нельзя / после мутации
notFound() сервер ресурса не существует

useRouter берётся из next/navigation, а не из next/router (это Pages Router).

Активная ссылка в меню

'use client'
const pathname = usePathname()
const active = pathname === href || pathname.startsWith(href + '/')

<Link href={href} aria-current={active ? 'page' : undefined}>...</Link>

Коротко

  • Layout = общий интерфейс, сохраняется при навигации; template = перемонтируется.
  • loading, error, not-found = состояния интерфейса, объявленные файлами.
  • <Link> для навигации без перезагрузки + prefetch; useRouter из next/navigation для навигации из кода.

Официальные источники

Упражнения

Была ли страница полезной?

Один клик — без регистрации.