#use react-hook-form with form action

1 messages · Page 1 of 1 (latest)

azure vine
#

This code doesn't trigger any validation on submit

const FormSchema = z.object({
  email: z
    .string()
    .min(1, { message: "." })
  password: z
    .string()
    .min(4, { message: "." }),
});

const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
    defaultValues: {
      email: "",
      password: "",
    },
  });

 const handleLogin = async (formData: FormData) => {
    const email = formData.get("email") as string;
    const password = formData.get("password") as string;
    let user = await signIn(email, password);
    if (isUser(user)) {
      const { email, isSignedIn, error } = user;
      if (!error.isError) {
        setSession(user);
        redirect("/dashboard");
      }
    }
  };

<Form {...form}>
      <form
        action={(formData) => startTransition(() => handleLogin(formData))}
        className="w-2/3 space-y-6"
      >
        <h1 className="text-4xl text-center font-semibold">Login</h1>
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input type="email" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="password"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Password</FormLabel>
              <FormControl>
                <Input type="password" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button
          type="submit"
          className="w-full"
          disabled={isPending}
        >
          Login
          {isPending ? (
            <ReloadIcon className="mx-2 h-4 w-4 animate-spin" />
          ) : null}
        </Button>
      </form>
    </Form>
upbeat coveBOT
#

Hi @azure vine. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Based on the information provided in the extracts, it seems like you're trying to use react-hook-form with a server action in Next.js. However, there seems to be a misunderstanding in how you're using the action prop in your form.

In Next.js, the action prop is used to specify a server action that should be invoked when the form is submitted. This server action is a function that is defined with the 'use server' directive and is typically imported from another file.

In your case, you're passing a function to the action prop that calls startTransition and then handleLogin. This is not the correct usage of the action prop. Instead, you should define a server action that handles the form submission and pass that to the action prop.

Here's an example of how you might define a server action for your form:

// actions.ts
'use server'

import { z } from 'zod'

const schema = z.object({
  email: z.string({
    invalid_type_error: 'Invalid Email',
  }),
  password: z.string({
    invalid_type_error: 'Invalid Password',
  }),
})

export default async function handleLogin(formData: FormData) {
  const validatedFields = schema.safeParse({
    email: formData.get('email'),
    password: formData.get('password'),
  })

  // Return early if the form data is invalid
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
    }
  }

  // Handle login
  // ...
}

Then, in your form component, you would import this server action and pass it to the action prop:

// LoginForm.tsx
'use client'

import { useFormState } from 'react-dom'
import handleLogin from '@/app/actions'

// ...

<form action={handleLogin} className="w-2/3 space-y-6">
  {/* ... */}
</form>

This way, when the form is submitted, the handleLogin server action will be invoked with the form data.