skip to Main Content

I’m using server actions to process data submitted with a form, and I want to clear the form into the action.

But the action does not receive the reference.

My action:

// actions/createVm.js
'use server'

export async function createVm(FormData) {
    const vm = await prisma.vm.create({
        data: {
            name: FormData.get("DisplayName"),
            ip: FormData.get("IpAddress"),
            group: {
                connect: { name: FormData.get("group") }
            }
        }
    })
    ref.current?.reset()
}

And the form :

// app/createVm/page.jsx
'use client'

import ButtonForm from "./button"
import { useRef } from "react"
import { createVm } from "@/actions/createVm"

export default function Form({ children }) {
  const ref = useRef(null)

    return(
        <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
            <form className="space-y-6" action={createVm} ref={ref}>
                { children }
                <ButtonForm />
            </form>
        </div>
    )
}

How can I use the reference?

2

Answers


  1. useRef is a client concept. It simply means "refrence to DOM element". You can’t pass DOM element to the server (there is no DOM on the server).

    How to clear the data?

    By using a client action:

    // app/createVm/page.jsx
    "use client";
    
    import ButtonForm from "./button";
    import { useRef } from "react";
    import { createVm } from "@/actions/createVm";
    
    export default function Form({ children }) {
        const ref = useRef(null);
    
        async function handleSubmit(formData) {
            // there is no directive here
    
            // run the server action
            await createVm(formData);
    
            ref.current.reset();
        }
    
        return (
            <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
                <form className="space-y-6" action={handleSubmit} ref={ref}>
                    {children}
                    <ButtonForm />
                </form>
            </div>
        );
    }
    
    // actions/createVm.js
    "use server";
    
    export async function createVm(FormData) {
        const vm = await prisma.vm.create({
            data: {
                name: FormData.get("DisplayName"),
                ip: FormData.get("IpAddress"),
                group: {
                    connect: { name: FormData.get("group") },
                },
            },
        });
    }
    
    
    Login or Signup to reply.
  2. if you are using server action, you can access to form state with useFormState

    // your action
    import { createVm } from "@/actions/createVm"
    
    const ref = useRef<HTMLFormElement | null>(null);
    
    const [formState, action] = useFormState(
        createVm.bind(null, { arg1, arg2 }),
        { errors: {} }
      );
    
    // if useFormState value changes, your component will rerendered
    // inside here using ref you can have control on form
    useEffect(() => {
        if (formState.success) {
          ref.current?.reset();      
        }
      }, [formState]);
    
    
     <form action={ createVm} ref={ref}>
     ....
     </form>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search