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.

pages/api/submit.ts
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:

pages/index.tsx
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:

pages/api/submit.ts
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:

pages/index.tsx
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:

pages/index.tsx
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:

pages/api/submit.ts
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:

pages/api/cookie.ts
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ı:

pages/api/cookie.ts
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:

pages/api/cookie.ts
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.')
}