Маршрутизация

Разделите приложение на маршруты с общим макетом, ссылками с сочетаниями клавиш и историей.

Приложение этой главы работает в вашей консоли. Откройте её сочетанием ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C (сначала включите функции разработчика), затем попробуйте приложение.
Смотреть главу3:46

В этой главе

  • Файлы как маршруты
  • Общий макет
  • Возврат назад
  • Динамические сегменты

App Router сопоставляет файлы в app/ с URL по соглашениям Next.js App Router. Адресная строка и история браузера синхронизированы, поэтому переходы назад, вперёд и прямые ссылки работают, пока интерфейс рендерится в консоли.

Файлы как маршруты

Перенесите список в отдельный маршрут и добавьте страницу настроек:

app/+5text
app/  layout.tsx  page.tsx                 → /Добавлено:   deployments/Добавлено:     page.tsx               → /deploymentsДобавлено:     [id]/page.tsx          → /deployments/dpl_8fK2Добавлено:   settings/Добавлено:     page.tsx               → /settings

Общий макет

layout.tsx оборачивает каждую страницу и сохраняет своё состояние при переходах. Разместите в нём верхнюю панель и навигацию.

app/layout.tsx+25tsx
Добавлено: import type { ReactNode } from "react";Добавлено: import { Box, Spacer, Text } from "@textjs/app";Добавлено: import Link from "@textjs/app/link";Добавлено: import { usePathname } from "@textjs/app/navigation";Добавлено: Добавлено: export const metadata = { title: { default: "Acme Deploys", template: "%s · Acme" } };Добавлено: Добавлено: export default function RootLayout({ children }: { children?: ReactNode }) {Добавлено:   const pathname = usePathname();Добавлено:   return (Добавлено:     <Box className="flex-col grow">Добавлено:       <Box className="flex-row h-1 px-1 gap-2">Добавлено:         <Text bold>▼ Acme</Text>Добавлено:         <Text color="subtle">{`acme.local${pathname === "/" ? "" : pathname}`}</Text>Добавлено:         <Spacer />Добавлено:       </Box>Добавлено:       <Box className="flex-row h-1 px-1 gap-3">Добавлено:         <Link href="/" shortcut="1">Overview</Link>Добавлено:         <Link href="/deployments" shortcut="2">Deployments</Link>Добавлено:         <Link href="/settings" shortcut="3">Settings</Link>Добавлено:       </Box>Добавлено:       <Box className="flex-col grow p-1">{children}</Box>Добавлено:     </Box>Добавлено:   );Добавлено: }

shortcut привязывает одну клавишу к ссылке. Нажмите 1, 2 и 3 в консоли; в реальном приложении URL менялся бы при каждом нажатии.

Возврат назад

useRouter() выполняет переходы из кода. Привяжите Backspace к router.back() в макете:

app/layout.tsx+7-2tsx
Удалено: import { Box, Spacer, Text } from "@textjs/app";Добавлено: import { Box, Spacer, Text, useInput } from "@textjs/app";import Link from "@textjs/app/link";Удалено: import { usePathname } from "@textjs/app/navigation";Добавлено: import { usePathname, useRouter } from "@textjs/app/navigation";export default function RootLayout({ children }: { children?: ReactNode }) {  const pathname = usePathname();Добавлено:   const router = useRouter();Добавлено: Добавлено:   useInput((e) => {Добавлено:     if (e.key === "backspace") router.back();Добавлено:   });

Динамические сегменты

Папки [id] получают своё значение в params:

app/deployments/[id]/page.tsxtsx
import { Text, type PageProps } from "@textjs/app";export default function DeploymentPage({ params }: PageProps<{ id: string }>) {  return <Text bold>{params.id}</Text>;}

На статическом хостинге для таких динамических сегментов нужно правило перезаписи на index.html. Это рассматривается в главе 10.

Попробовать

Это Acme Deploys в конце главы, работающее в DevTools. Нажмите на панель, затем используйте клавиши ниже.

▼ 05 · Маршрутизация

Открыть консоль

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

Приложение рендерится в DevTools.Сначала включите «Показывать функции для веб-разработчиков» в Safari: «Настройки» → «Дополнения». Затем щёлкните здесь и нажмите 2.

Открыть на компьютере

Это приложение рендерится в консоли DevTools, для которой нужен браузер на компьютере.

Тест

2 вопроса

Ответьте на все вопросы, чтобы завершить главу.

Какой файл рендерится по адресу /deployments?

 

Что сохраняется при переходе между страницами?