v2.5.2
Giriş yap

NextJS FormAction sonrasinda nasil handle code calistirilir?

kaanchnr
77 defa görüntülendi ve 1 kişi tarafından değerlendirildi

Sorum biraz garip aslinda cunku ben de nasil anlatilir bilmiyorum.

Ben NextJS ile bir form olusturdum ve bu formdan aldigim verileri FormActions ile PostgreSQL veritabanima yaziyorum. Fakat burada boyle bir sorun var ki, ben verinin gonderilip-gonderilmedigini kullaniciya Toast notification ile bildirmek istiyorum.
Her sey normal calisiyor ama bir sorun var. Ben formu submit butonuna tikladigim zaman benim initial degerim geliyor. Ikinci kez tikladigimda bu sefer calisiyor ve toast notification gozukuyor. Fakat bir sure sonra komple sayfam cokuyor.
onSubmit ve onClick eventleri ile toast bildiriminin formu gonderdikten sonraya ayarlasam da anlattigim olay ayni sekilde.

React Formum bu sekilde:

'use client'

import { useRouter } from 'next/navigation'
import { useFormState, useFormStatus } from 'react-dom'
import { createMessage } from '@/actions/action'
import { useEffect } from 'react'
import { toast } from 'react-toastify';

const initialState = {
    name: '',
    surname: '',
    phone: '',
    mail: '',
    message: '',
    status: 'initial',
    success: false
}


function Form(){
  const [state, formAction] = useFormState(createMessage, initialState);
  const { pending } = useFormStatus()
  const { status , success} = state
  


  const handleClick = async (event:any) => {
    console.log(status)


  }
  return (
    
    <div className='text-center p-10 text-Background'>
    <form action={formAction} className='max-w-md mx-auto lg:p-8' onSubmit={handleClick}>
            <div className='space-y-4'>
            <input type="text" name='name' placeholder="First Name" className='w-full p-2 border rounded-xs outline-none' required/>
            <input type="text" name='surname' placeholder="Last Name" className='w-full p-2 border rounded-xs outline-none' required/>
            <input type="tel" name='phone' placeholder="Phone Number" className='w-full p-2 border rounded-xs outline-none' required/>
            <input type="email" name='mail' placeholder="Mail address" className='w-full p-2 border rounded-xs outline-none' required/>
            <textarea name="message" placeholder="Write your message:" 
                      className='w-full p-2 border rounded-xs h-32 resize-none outline-none'
                      required></textarea>
        </div>
        <button type="submit" aria-disabled={pending} className="font-bold p-2.5 bg-Primary hover:bg-Accent text-Text transition rounded-xs">Submit!</button>
    </form>
    
</div>

  )
}

export default Form

Formaction fonksiyonum ise bu sekilde:

'use server'

import { revalidatePath } from "next/cache"
import { PrismaClient } from '@prisma/client'
import {z} from 'zod'

const prisma = new PrismaClient()

export async function createMessage(prevState:{status: string, success: boolean}, formData: FormData){
    const schema = z.object({
        name: z.string().min(3),
        surname: z.string(),
        phone: z.string().min(10),
        mail: z.string(),
        message: z.string().min(10)
    })

    const parse = schema.safeParse({
        name: formData.get('name'),
        surname: formData.get('surname'),
        phone: formData.get('phone'),
        mail: formData.get('mail'),
        message: formData.get('message')
    })

    if(!parse.success){
        return { status: "Failed to send message", success: false}
    }

    const {name, surname, mail, phone, message} = parse.data

    try {
        await prisma.user.create({
            data: {
                name,
                surname,
                email: mail,
                phone,
                message
            }
        })
        revalidatePath('/')
        return {
            status: "Message sent",
            success: true
        }
    }
    catch(e){
        return {
            status: "Failed to send message",
            success: false
        }
    }
}

Amacim actionda dondurdugum degerleri form sayfamda toast olarak gostermek. Nasil bu hatadan kurtulurum?

Cevap yaz
Cevaplar (1)
mhmnm
33 gün önce

Merhaba kardeşim. useEffect ile state-de değişiklik olub-olmadığına bakmalısın. Bunla beraber onSubmit-e ihtiyaç yok zaten action-dan sana değer dönecektir. Birde initialState-e sadece döndürdüğün değerleri(success ve status) yazmalısın. Son olarak useFormStatus-u button-u ayrıca component yapıp onun içerisine koymalısın. Kullanım Örnek:


'use client'

import { useRouter } from 'next/navigation'
import { useFormState, useFormStatus } from 'react-dom'
import { createMessage } from '@/actions/action'
import { useEffect } from 'react'
import { toast } from 'react-toastify';

const initialState = {
    status: '',
    success: false
}


function Form(){
  const [state, formAction] = useFormState(createMessage, initialState);
  

    useEffect(() => {
        console.log(state?.status, state?.success) // toast-la göstere bilirsin
    }, [state?.status, state?.success)
  return (
    
    <div className='text-center p-10 text-Background'>
    <form action={formAction} className='max-w-md mx-auto lg:p-8'>
        <div className='space-y-4'>
            <input type="text" name='name' placeholder="First Name" className='w-full p-2 border rounded-xs outline-none' required/>
            <input type="text" name='surname' placeholder="Last Name" className='w-full p-2 border rounded-xs outline-none' required/>
            <input type="tel" name='phone' placeholder="Phone Number" className='w-full p-2 border rounded-xs outline-none' required/>
            <input type="email" name='mail' placeholder="Mail address" className='w-full p-2 border rounded-xs outline-none' required/>
            <textarea name="message" placeholder="Write your message:" className='w-full p-2 border rounded-xs h-32 resize-none outline-none'required></textarea>
        </div>
       <SubmitButton />
    </form>
    
</div>

  )
}

export default Form



function SubmitButton() {
  const {pending} = useFormStatus();
  return <button disabled={pending}>Submit</button>
}