Seiten und Layouts
Der Pages Router basiert auf einem dateisystembasierten Routing-Konzept mit Seiten.
Wenn eine Datei zum pages
-Verzeichnis hinzugefügt wird, ist sie automatisch als Route verfügbar.
In Next.js ist eine Seite eine React-Komponente, die aus einer .js
-, .jsx
-, .ts
- oder .tsx
-Datei im pages
-Verzeichnis exportiert wird. Jede Seite ist mit einer Route verknüpft, die auf ihrem Dateinamen basiert.
Beispiel: Wenn Sie pages/about.js
erstellen, die eine React-Komponente wie unten exportiert, ist sie unter /about
erreichbar.
export default function About() {
return <div>About</div>
}
Index-Routen
Der Router leitet Dateien namens index
automatisch zum Stammverzeichnis weiter.
pages/index.js
→/
pages/blog/index.js
→/blog
Verschachtelte Routen
Der Router unterstützt verschachtelte Dateien. Wenn Sie eine verschachtelte Ordnerstruktur erstellen, werden die Dateien weiterhin auf dieselbe Weise geroutet.
pages/blog/first-post.js
→/blog/first-post
pages/dashboard/settings/username.js
→/dashboard/settings/username
Seiten mit dynamischen Routen
Next.js unterstützt Seiten mit dynamischen Routen. Wenn Sie beispielsweise eine Datei namens pages/posts/[id].js
erstellen, ist sie unter posts/1
, posts/2
usw. erreichbar.
Weitere Informationen zum dynamischen Routing finden Sie in der Dokumentation zu dynamischen Routen.
Layout-Muster
Das React-Modell ermöglicht es uns, eine Seite in eine Reihe von Komponenten zu zerlegen. Viele dieser Komponenten werden oft zwischen Seiten wiederverwendet. Beispielsweise könnten Sie auf jeder Seite dieselbe Navigationsleiste und Fußzeile haben.
import Navbar from './navbar'
import Footer from './footer'
export default function Layout({ children }) {
return (
<>
<Navbar />
<main>{children}</main>
<Footer />
</>
)
}
Beispiele
Einzelnes gemeinsames Layout mit Custom App
Wenn Sie nur ein Layout für Ihre gesamte Anwendung haben, können Sie eine Custom App erstellen und Ihre Anwendung mit dem Layout umschließen. Da die <Layout />
-Komponente beim Wechsel der Seiten wiederverwendet wird, bleibt ihr Komponentenzustand erhalten (z. B. Eingabewerte).
import Layout from '../components/layout'
export default function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
Layouts pro Seite
Wenn Sie mehrere Layouts benötigen, können Sie eine Eigenschaft getLayout
zu Ihrer Seite hinzufügen, die es Ihnen ermöglicht, eine React-Komponente für das Layout zurückzugeben. Dies ermöglicht es Ihnen, das Layout auf einer pro-Seite-Basis zu definieren. Da wir eine Funktion zurückgeben, können wir bei Bedarf komplexe verschachtelte Layouts haben.
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
export default function Page() {
return (
/** Ihr Inhalt */
)
}
Page.getLayout = function getLayout(page) {
return (
<Layout>
<NestedLayout>{page}</NestedLayout>
</Layout>
)
}
export default function MyApp({ Component, pageProps }) {
// Verwenden Sie das auf Seitenebene definierte Layout, falls verfügbar
const getLayout = Component.getLayout ?? ((page) => page)
return getLayout(<Component {...pageProps} />)
}
Beim Navigieren zwischen Seiten möchten wir den Seitenzustand (Eingabewerte, Scrollposition usw.) für eine Single-Page Application (SPA)-Erfahrung beibehalten.
Dieses Layout-Muster ermöglicht die Zustandserhaltung, da der React-Komponentenbaum zwischen Seitenübergängen erhalten bleibt. Mit dem Komponentenbaum kann React verstehen, welche Elemente sich geändert haben, um den Zustand zu erhalten.
Gut zu wissen: Dieser Prozess wird als Reconciliation bezeichnet und beschreibt, wie React erkennt, welche Elemente sich geändert haben.
Mit TypeScript
Bei Verwendung von TypeScript müssen Sie zunächst einen neuen Typ für Ihre Seiten erstellen, der eine getLayout
-Funktion enthält. Dann müssen Sie einen neuen Typ für Ihre AppProps
erstellen, der die Component
-Eigenschaft überschreibt, um den zuvor erstellten Typ zu verwenden.
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 Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
const Page = () => {
return <p>hello world</p>
}
Page.getLayout = function getLayout(page) {
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) {
// Verwenden Sie das auf Seitenebene definierte Layout, falls verfügbar
const getLayout = Component.getLayout ?? ((page) => page)
return getLayout(<Component {...pageProps} />)
}
export default function MyApp({ Component, pageProps }) {
// Verwenden Sie das auf Seitenebene definierte Layout, falls verfügbar
const getLayout = Component.getLayout ?? ((page) => page)
return getLayout(<Component {...pageProps} />)
}
Datenabruf
In Ihrem Layout können Sie clientseitig Daten mit useEffect
oder einer Bibliothek wie SWR abrufen. Da diese Datei keine Seite ist, können Sie derzeit getStaticProps
oder getServerSideProps
nicht verwenden.
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>Fehler beim Laden</div>
if (!data) return <div>Laden...</div>
return (
<>
<Navbar links={data.links} />
<main>{children}</main>
<Footer />
</>
)
}