Spec-Zone.ru › Next.js

Страницы и макеты

Маршрутизатор страниц имеет маршрутизатор, основанный на файловой системе и построенный на концепции страниц.

При добавлении файла в каталог pages он автоматически становится доступным в качестве маршрута.

В Next.js, страница — это компонент React, экспортируемый из файла .js, .jsx, .ts, или .tsx в каталоге pages. Каждая страница связана с маршрутом, основанным на её имени файла.

Пример: Если вы создадите pages/about.js, который экспортирует компонент React, как показано ниже, он будет доступен по адресу /about.

export default function About() {
  return <div>About</div>
}

Маршруты по умолчанию

Маршрутизатор автоматически обрабатывает файлы, имеющие имя index, как маршруты корневого каталога.

  • pages/index.js → /
  • pages/blog/index.js → /blog

Вложенные маршруты

Маршрутизатор поддерживает вложенные файлы. Если вы создадите вложенную структуру каталогов, файлы будут маршрутизироваться аналогичным образом.

  • pages/blog/first-post.js → /blog/first-post
  • pages/dashboard/settings/username.js → /dashboard/settings/username

Страницы с динамическими маршрутами

Next.js поддерживает страницы с динамическими маршрутами. Например, если вы создадите файл с именем pages/posts/[id].js, он будет доступен по адресам posts/1, posts/2, и т. д.

Дополнительную информацию о динамическом маршрутировании можно найти в документации по динамическому маршрутированию.

Паттерн макета

Модель React позволяет нам разбить страницу на ряд компонентов. Многие из этих компонентов часто используются на нескольких страницах. Например, на каждой странице может быть одинаковая навигационная панель и подвал.

import Navbar from './navbar'
import Footer from './footer'
 
export default function Layout({ children }) {
  return (
    <>
      <Navbar />
      <main>{children}</main>
      <Footer />
    </>
  )
}

Примеры

Один общий макет с настраиваемым приложением

Если для всего приложения используется только один макет, вы можете создать настраиваемое приложение и обернуть ваше приложение этим макетом. Поскольку компонент <Layout /> повторно используется при переходе на другие страницы, его состояние компонента сохраняется (например, значения ввода).

import Layout from '../components/layout'
 
export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  )
}

Макеты для каждой страницы

Если вам нужны несколько макетов, вы можете добавить свойство getLayout на вашу страницу, что позволит вам вернуть компонент React для макета. Это позволяет определять макет для каждой страницы индивидуально. Поскольку мы возвращаем функцию, можно создавать сложные вложенные макеты по необходимости.

 
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
 
export default function Page() {
  return (
    /** Your content */
  )
}
 
Page.getLayout = function getLayout(page) {
  return (
    <Layout>
      <NestedLayout>{page}</NestedLayout>
    </Layout>
  )
}
export default function MyApp({ Component, pageProps }) {
  // Use the layout defined at the page level, if available
  const getLayout = Component.getLayout ?? ((page) => page)
 
  return getLayout(<Component {...pageProps} />)
}

При переходе между страницами мы хотим сохранить состояние страницы (значения ввода, положение прокрутки и т. д.) для работы с одностраничным приложением (SPA).

Этот шаблон макетов позволяет сохранять состояние, потому что дерево компонентов React сохраняется при переходах между страницами. С деревом компонентов React может понять, какие элементы изменились для сохранения состояния.

Важно знать: этот процесс называется слиянием, с помощью которого React определяет, какие элементы изменились.

С TypeScript

При использовании TypeScript необходимо сначала создать новый тип для ваших страниц, который включает функцию getLayout. Затем необходимо создать новый тип для вашего AppProps, который переопределяет свойство Component для использования ранее созданного типа.

import type { ReactElement } from 'react'
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
import type { NextPageWithLayout } from './_app'
 
const Page: NextPageWithLayout = () => {
  return <p>hello world</p>
}
 
Page.getLayout = function getLayout(page: ReactElement) {
  return (
    <Layout>
      <NestedLayout>{page}</NestedLayout>
    </Layout>
  )
}
 
export default Page
import type { ReactElement, ReactNode } from 'react'
import type { NextPage } from 'next'
import type { AppProps } from 'next/app'
 
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
  getLayout?: (page: ReactElement) => ReactNode
}
 
type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout
}
 
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  // Use the layout defined at the page level, if available
  const getLayout = Component.getLayout ?? ((page) => page)
 
  return getLayout(<Component {...pageProps} />)
}

Получение данных

Внутри макета вы можете получать данные на стороне клиента, используя useEffect или библиотеку, такую как SWR. Поскольку этот файл не является страницей, вы не можете использовать getStaticProps или getServerSideProps в настоящее время.

import useSWR from 'swr'
import Navbar from './navbar'
import Footer from './footer'
 
export default function Layout({ children }) {
  const { data, error } = useSWR('/api/navigation', fetcher)
 
  if (error) return <div>Failed to load</div>
  if (!data) return <div>Loading...</div>
 
  return (
    <>
      <Navbar links={data.links} />
      <main>{children}</main>
      <Footer />
    </>
  )
}

© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API