Formular

Die <Form>-Komponente erweitert das HTML-<form>-Element um Prefetching von Lade-UI, Client-seitige Navigation bei Übermittlung und progressive Verbesserung.

Sie ist besonders nützlich für Formulare, die URL-Suchparameter aktualisieren, da sie den Boilerplate-Code reduziert, der für die oben genannten Funktionen benötigt wird.

Grundlegende Verwendung:

import Form from 'next/form'

export default function Page() {
  return (
    <Form action="/search">
      {/* Bei Übermittlung wird der Eingabewert an
          die URL angehängt, z.B. /search?query=abc */}
      <input name="query" />
      <button type="submit">Submit</button>
    </Form>
  )
}
import Form from 'next/form'

export default function Search() {
  return (
    <Form action="/search">
      {/* Bei Übermittlung wird der Eingabewert an
          die URL angehängt, z.B. /search?query=abc */}
      <input name="query" />
      <button type="submit">Submit</button>
    </Form>
  )
}

Referenz

Das Verhalten der <Form>-Komponente hängt davon ab, ob der action-Prop einen string oder eine function erhält.

  • Wenn action ein String ist, verhält sich <Form> wie ein natives HTML-Formular mit GET-Methode. Die Formulardaten werden als Suchparameter in die URL kodiert, und bei Übermittlung wird zur angegebenen URL navigiert. Zusätzlich führt Next.js folgendes durch:
    • Prefetching des Pfads, wenn das Formular sichtbar wird, wodurch gemeinsame UI (z.B. layout.js und loading.js) vorab geladen wird, was zu schnellerer Navigation führt.
    • Führt eine Client-seitige Navigation anstelle eines vollständigen Seiten-Neuladens durch, was gemeinsame UI und Client-seitigen Zustand erhält.
  • Wenn action eine Funktion (Server Action) ist, verhält sich <Form> wie ein React-Formular, das die Action bei Übermittlung ausführt.

action (string) Props

Wenn action ein String ist, unterstützt die <Form>-Komponente folgende Props:

PropBeispielTypErforderlich
actionaction="/search"string (URL oder relativer Pfad)Ja
replacereplace={false}boolean-
scrollscroll={true}boolean-
prefetchprefetch={true}boolean-
  • action: Die URL oder der Pfad, zu dem bei Formularübermittlung navigiert werden soll.
    • Ein leerer String "" navigiert zur gleichen Route mit aktualisierten Suchparametern.
  • replace: Ersetzt den aktuellen Verlaufseintrag anstatt einen neuen zum Browserverlauf hinzuzufügen. Standard ist false.
  • scroll: Steuert das Scrollverhalten während der Navigation. Standard ist true, was bedeutet, dass zum Anfang der neuen Route gescrollt wird und die Scrollposition für Vor- und Zurück-Navigation beibehalten wird.
  • prefetch: Steuert, ob der Pfad vorab geladen werden soll, wenn das Formular im Sichtbereich des Benutzers erscheint. Standard ist true.

action (function) Props

Wenn action eine Funktion ist, unterstützt die <Form>-Komponente folgende Prop:

PropBeispielTypErforderlich
actionaction={myAction}function (Server Action)Ja
  • action: Die Server Action, die bei Formularübermittlung aufgerufen wird. Siehe React-Dokumentation für mehr.

Gut zu wissen: Wenn action eine Funktion ist, werden die Props replace und scroll ignoriert.

Einschränkungen

  • formAction: Kann in <button>- oder <input type="submit">-Feldern verwendet werden, um die action-Prop zu überschreiben. Next.js führt eine Client-seitige Navigation durch, unterstützt jedoch kein Prefetching.
    • Bei Verwendung von basePath muss dieser auch im formAction-Pfad enthalten sein, z.B. formAction="/base-path/search".
  • key: Das Übergeben einer key-Prop an eine String-action wird nicht unterstützt. Wenn Sie ein Re-Rendering auslösen oder eine Mutation durchführen möchten, sollten Sie stattdessen eine Funktions-action verwenden.
  • onSubmit: Kann zur Behandlung von Formularübermittlungslogik verwendet werden. Der Aufruf von event.preventDefault() überschreibt jedoch das <Form>-Verhalten wie die Navigation zur angegebenen URL.
  • method, encType, target: Werden nicht unterstützt, da sie das <Form>-Verhalten überschreiben.
    • Ähnlich können formMethod, formEncType und formTarget verwendet werden, um die method-, encType- und target-Props zu überschreiben, wodurch das native Browserverhalten wiederhergestellt wird.
    • Wenn Sie diese Props benötigen, verwenden Sie stattdessen das HTML-<form>-Element.
  • <input type="file">: Die Verwendung dieses Eingabetyps bei einer String-action entspricht dem Browserverhalten, indem der Dateiname anstelle des Dateiobjekts übermittelt wird.

Beispiele

Suchformular, das zu einer Suchergebnisseite führt

Sie können ein Suchformular erstellen, das zu einer Suchergebnisseite navigiert, indem Sie den Pfad als action übergeben:

import Form from 'next/form'

export default function Page() {
  return (
    <Form action="/search">
      <input name="query" />
      <button type="submit">Submit</button>
    </Form>
  )
}
import Form from 'next/form'

export default function Page() {
  return (
    <Form action="/search">
      <input name="query" />
      <button type="submit">Submit</button>
    </Form>
  )
}

Wenn der Benutzer das Abfrage-Eingabefeld aktualisiert und das Formular übermittelt, werden die Formulardaten als Suchparameter in die URL kodiert, z.B. /search?query=abc.

Gut zu wissen: Wenn Sie einen leeren String "" an action übergeben, navigiert das Formular zur gleichen Route mit aktualisierten Suchparametern.

Auf der Ergebnisseite können Sie die Abfrage mit dem searchParams-Prop von page.js abrufen und damit Daten aus einer externen Quelle abfragen.

import { getSearchResults } from '@/lib/search'

export default async function SearchPage({
  searchParams,
}: {
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
  const results = await getSearchResults((await searchParams).query)

  return <div>...</div>
}
import { getSearchResults } from '@/lib/search'

export default async function SearchPage({ searchParams }) {
  const results = await getSearchResults((await searchParams).query)

  return <div>...</div>
}

Wenn die <Form> im Sichtbereich des Benutzers erscheint, wird die gemeinsame UI (wie layout.js und loading.js) auf der /search-Seite vorab geladen. Bei Übermittlung navigiert das Formular sofort zur neuen Route und zeigt die Lade-UI an, während die Ergebnisse abgerufen werden. Sie können die Fallback-UI mit loading.js gestalten:

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

Für Fälle, in denen die gemeinsame UI noch nicht geladen ist, können Sie dem Benutzer mit useFormStatus sofortiges Feedback geben.

Erstellen Sie zunächst eine Komponente, die einen Ladezustand anzeigt, wenn das Formular aussteht:

'use client'
import { useFormStatus } from 'react-dom'

export default function SearchButton() {
  const status = useFormStatus()
  return (
    <button type="submit">{status.pending ? 'Suche...' : 'Suchen'}</button>
  )
}
'use client'
import { useFormStatus } from 'react-dom'

export default function SearchButton() {
  const status = useFormStatus()
  return (
    <button type="submit">{status.pending ? 'Suche...' : 'Suchen'}</button>
  )
}

Aktualisieren Sie dann die Suchformularseite, um die SearchButton-Komponente zu verwenden:

import Form from 'next/form'
import { SearchButton } from '@/ui/search-button'

export default function Page() {
  return (
    <Form action="/search">
      <input name="query" />
      <SearchButton />
    </Form>
  )
}
import Form from 'next/form'
import { SearchButton } from '@/ui/search-button'

export default function Page() {
  return (
    <Form action="/search">
      <input name="query" />
      <SearchButton />
    </Form>
  )
}

Mutationen mit Server Actions

Sie können Mutationen durchführen, indem Sie eine Funktion an den action-Prop übergeben.

import Form from 'next/form'
import { createPost } from '@/posts/actions'

export default function Page() {
  return (
    <Form action={createPost}>
      <input name="title" />
      {/* ... */}
      <button type="submit">Beitrag erstellen</button>
    </Form>
  )
}
import Form from 'next/form'
import { createPost } from '@/posts/actions'

export default function Page() {
  return (
    <Form action={createPost}>
      <input name="title" />
      {/* ... */}
      <button type="submit">Beitrag erstellen</button>
    </Form>
  )
}

Nach einer Mutation ist es üblich, zur neuen Ressource umzuleiten. Sie können die redirect-Funktion von next/navigation verwenden, um zur neuen Beitragsseite zu navigieren.

Gut zu wissen: Da das "Ziel" der Formularübermittlung erst nach Ausführung der Action bekannt ist, kann <Form> die gemeinsame UI nicht automatisch vorab laden.

'use server'
import { redirect } from 'next/navigation'

export async function createPost(formData: FormData) {
  // Neuen Beitrag erstellen
  // ...

  // Zum neuen Beitrag umleiten
  redirect(`/posts/${data.id}`)
}
'use server'
import { redirect } from 'next/navigation'

export async function createPost(formData) {
  // Neuen Beitrag erstellen
  // ...

  // Zum neuen Beitrag umleiten
  redirect(`/posts/${data.id}`)
}

Dann können Sie auf der neuen Seite Daten mit dem params-Prop abrufen:

import { getPost } from '@/posts/data'

export default async function PostPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  const data = await getPost(id)

  return (
    <div>
      <h1>{data.title}</h1>
      {/* ... */}
    </div>
  )
}
import { getPost } from '@/posts/data'

export default async function PostPage({ params }) {
  const { id } = await params
  const data = await getPost(id)

  return (
    <div>
      <h1>{data.title}</h1>
      {/* ... */}
    </div>
  )
}

Weitere Beispiele finden Sie in der Server Actions-Dokumentation.