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
Nur-Server-Formular
Mit dem Pages-Router müssen Sie manuell API-Endpunkte erstellen, um Daten sicher auf dem Server zu mutieren.
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 handhaben
const data = await response.json()
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</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 handhaben
const data = await response.json()
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
)
}
Formularvalidierung
Wir empfehlen die Verwendung von HTML-Validierung wie required
und type="email"
für grundlegende clientseitige Formularvalidierung.
Für erweiterte serverseitige Validierung können Sie eine Schema-Validierungsbibliothek wie zod verwenden, um die Formularfelder vor der Datenmutation 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)
// ...
}
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 bei einer neuen Anfrage löschen
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 handhaben
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 ? 'Laden...' : '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 bei einer neuen Anfrage löschen
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 handhaben
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 ? 'Laden...' : 'Submit'}
</button>
</form>
</div>
)
}
Anzeigen des Ladezustands
Sie können 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 Beginn 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 handhaben
const data = await response.json()
// ...
} catch (error) {
// Fehler bei Bedarf handhaben
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 ? 'Laden...' : 'Submit'}
</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 Beginn 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 handhaben
const data = await response.json()
// ...
} catch (error) {
// Fehler bei Bedarf handhaben
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 ? 'Laden...' : 'Submit'}
</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}`)
}
Cookies setzen
Sie können Cookies in einer API-Route mit der setHeader
-Methode der Antwort setzen:
Cookies lesen
Sie können Cookies in einer API-Route mit dem cookies
-Request-Helfer lesen:
Cookies löschen
Sie können Cookies in einer API-Route mit der setHeader
-Methode der Antwort löschen: