Formulare und Mutationen
Formulare ermöglichen Ihnen das Erstellen und Aktualisieren von Daten in Webanwendungen. Next.js bietet eine leistungsstarke Möglichkeit, Formularübermittlungen und Datenmutationen mit API-Routen zu handhaben.
Gut zu wissen:
- Wir werden bald die schrittweise Einführung des App-Routers empfehlen und Server Actions für die Handhabung von Formularübermittlungen und Datenmutationen verwenden. Server Actions ermöglichen es Ihnen, asynchrone Serverfunktionen zu definieren, die direkt aus Ihren Komponenten aufgerufen werden können, ohne manuell eine API-Route erstellen zu müssen.
- API-Routen legen keine CORS-Header fest, was bedeutet, dass sie standardmäßig nur same-origin sind.
- Da API-Routen auf dem Server ausgeführt werden, können wir sensible Werte (wie API-Schlüssel) über Umgebungsvariablen verwenden, ohne sie dem Client preiszugeben. Dies ist entscheidend für die Sicherheit Ihrer Anwendung.
Beispiele
Server-exklusive Formulare
Mit dem Pages-Router müssen Sie manuell API-Endpunkte erstellen, um Datenmutationen auf dem Server sicher zu handhaben.
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const data = req.body
const id = await createItem(data)
res.status(200).json({ id })
}
export default function handler(req, res) {
const data = req.body
const id = await createItem(data)
res.status(200).json({ id })
}
Rufen Sie dann die API-Route vom Client mit einem Event-Handler auf:
import { FormEvent } from 'react'
export default function Page() {
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Antwort bei Bedarf verarbeiten
const data = await response.json()
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Absenden</button>
</form>
)
}
export default function Page() {
async function onSubmit(event) {
event.preventDefault()
const formData = new FormData(event.target)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Antwort bei Bedarf verarbeiten
const data = await response.json()
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Absenden</button>
</form>
)
}
Weiterleitung
Wenn Sie den Benutzer nach einer Mutation zu einer anderen Route weiterleiten möchten, können Sie mit redirect
zu einer absoluten oder relativen URL weiterleiten:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const id = await addPost()
res.redirect(307, `/post/${id}`)
}
export default async function handler(req, res) {
const id = await addPost()
res.redirect(307, `/post/${id}`)
}
Formularvalidierung
Wir empfehlen die Verwendung von HTML-Validierung wie required
und type="email"
für grundlegende Formularvalidierung.
Für erweiterte serverseitige Validierung verwenden Sie eine Schema-Validierungsbibliothek wie zod, um die Struktur der geparsten Formulardaten zu validieren:
import type { NextApiRequest, NextApiResponse } from 'next'
import { z } from 'zod'
const schema = z.object({
// ...
})
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const parsed = schema.parse(req.body)
// ...
}
import { z } from 'zod'
const schema = z.object({
// ...
})
export default async function handler(req, res) {
const parsed = schema.parse(req.body)
// ...
}
Anzeigen des Ladezustands
Sie können den React-State verwenden, um einen Ladezustand anzuzeigen, wenn ein Formular auf dem Server übermittelt wird:
import React, { useState, FormEvent } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState<boolean>(false)
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()
setIsLoading(true) // Ladezustand bei Start der Anfrage auf true setzen
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Antwort bei Bedarf verarbeiten
const data = await response.json()
// ...
} catch (error) {
// Fehler bei Bedarf verarbeiten
console.error(error)
} finally {
setIsLoading(false) // Ladezustand bei Abschluss der Anfrage auf false setzen
}
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Lädt...' : 'Absenden'}
</button>
</form>
)
}
import React, { useState } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState(false)
async function onSubmit(event) {
event.preventDefault()
setIsLoading(true) // Ladezustand bei Start der Anfrage auf true setzen
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Antwort bei Bedarf verarbeiten
const data = await response.json()
// ...
} catch (error) {
// Fehler bei Bedarf verarbeiten
console.error(error)
} finally {
setIsLoading(false) // Ladezustand bei Abschluss der Anfrage auf false setzen
}
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Lädt...' : 'Absenden'}
</button>
</form>
)
}
Fehlerbehandlung
Sie können React State verwenden, um eine Fehlermeldung anzuzeigen, wenn eine Formularübermittlung fehlschlägt:
import React, { useState, FormEvent } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState<boolean>(false)
const [error, setError] = useState<string | null>(null)
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()
setIsLoading(true)
setError(null) // Vorherige Fehler löschen, wenn eine neue Anfrage startet
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
if (!response.ok) {
throw new Error('Failed to submit the data. Please try again.')
}
// Antwort bei Bedarf verarbeiten
const data = await response.json()
// ...
} catch (error) {
// Fehlermeldung erfassen, um sie dem Benutzer anzuzeigen
setError(error.message)
console.error(error)
} finally {
setIsLoading(false)
}
}
return (
<div>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
</div>
)
}
import React, { useState } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState(null)
async function onSubmit(event) {
event.preventDefault()
setIsLoading(true)
setError(null) // Vorherige Fehler löschen, wenn eine neue Anfrage startet
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
if (!response.ok) {
throw new Error('Failed to submit the data. Please try again.')
}
// Antwort bei Bedarf verarbeiten
const data = await response.json()
// ...
} catch (error) {
// Fehlermeldung erfassen, um sie dem Benutzer anzuzeigen
setError(error.message)
console.error(error)
} finally {
setIsLoading(false)
}
}
return (
<div>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
</div>
)
}
Cookies setzen
Sie können Cookies in einer API-Route mit der setHeader
-Methode der Antwort setzen:
Cookies auslesen
Sie können Cookies in einer API-Route mit dem cookies
-Request-Helper auslesen:
Cookies löschen
Sie können Cookies in einer API-Route mit der setHeader
-Methode der Antwort löschen: