Forms and Mutations
Formlar, web uygulamalarında veri oluşturmanızı ve güncellemenizi sağlar. Next.js, API Routes kullanarak form gönderimlerini ve veri mutasyonlarını işlemek için güçlü bir yol sağlar.
Bilmekte fayda var:
- Yakında App Router'ı aşamalı olarak benimsemenizi ve form gönderimleri ile veri mutasyonlarını işlemek için Sunucu Eylemlerini kullanmanızı önereceğiz. Sunucu Eylemleri, manuel olarak bir API Rotası oluşturmanıza gerek kalmadan doğrudan bileşenlerinizden çağrılabilen eşzamansız sunucu işlevleri tanımlamanıza olanak tanır.
- API Rotaları CORS başlıklarını belirtmez, yani varsayılan olarak yalnızca aynı kaynaklıdırlar.
- API Rotaları sunucu üzerinde çalıştığından, hassas değerleri (API anahtarları gibi) istemciye göstermeden Ortam Değişkenleriaracılığıyla kullanabiliyoruz. Bu, uygulamanızın güvenliği için kritik öneme sahiptir.
Examples
Server-only form
Pages Router ile, sunucuda güvenli bir şekilde değişen verileri işlemek için API uç noktalarını manuel olarak oluşturmanız gerekir.
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 })
}
Ardından, API Rotasını istemciden bir olay işleyicisi ile çağırın:
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,
})
// Handle response if necessary
const data = await response.json()
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
)
}
Form validation
Temel istemci tarafı form doğrulaması için required
ve type="email"
gibi HTML
doğrulamalarını kullanmanızı öneririz.
Daha gelişmiş sunucu tarafı doğrulama için, verileri değiştirmeden önce form alanlarını doğrulamak üzere zod gibi bir şema doğrulama kütüphanesi kullanabilirsiniz:
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)
// ...
}
Error handling
Form gönderimi başarısız olduğunda bir hata mesajı göstermek için React state'i kullanabilirsiniz:
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) // Clear previous errors when a new request starts
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.')
}
// Handle response if necessary
const data = await response.json()
// ...
} catch (error) {
// Capture the error message to display to the user
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>
)
}
Displaying loading state
Sunucuda bir form gönderilirken yükleme durumunu göstermek için React state'i kullanabilirsiniz:
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) // Set loading to true when the request starts
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Handle response if necessary
const data = await response.json()
// ...
} catch (error) {
// Handle error if necessary
console.error(error)
} finally {
setIsLoading(false) // Set loading to false when the request completes
}
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
)
}
Redirecting
Bir mutasyondan sonra kullanıcıyı farklı bir rotaya yönlendirmek isterseniz şunları yapabilirsiniz
redirect
herhangi bir mutlak veya göreli URL'ye:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const id = await addPost()
res.redirect(307, `/post/${id}`)
}
Setting cookies
Yanıtta setHeader
yöntemini kullanarak bir API Rotası içinde çerezleri ayarlayabilirsiniz:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
res.setHeader('Set-Cookie', 'username=lee; Path=/; HttpOnly')
res.status(200).send('Cookie has been set.')
}
Reading cookies
kullanarak bir API Rotası içindeki çerezleri okuyabilirsiniz.
cookies
istek yardımcısı:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const auth = req.cookies.authorization
// ...
}
Deleting cookies
Yanıttaki setHeader
yöntemini kullanarak bir API Rotası içindeki çerezleri silebilirsiniz:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
res.setHeader('Set-Cookie', 'username=; Path=/; HttpOnly; Max-Age=0')
res.status(200).send('Cookie has been deleted.')
}