When using a form, the useActionState hook simplifies the process of capturing form values and passing them to a server action as FormData.
useActionState also manages state by automatically updating a state variable with the value returned from the server action. This is particularly helpful for rendering input field validation errors, as shown in the example below using Zod.
form.tsx:
"use client"; import { useActionState } from "react"; import { signUp } from "../actions"; export default function SignUp() { const [state, action] = useActionState(signUp, {}); return ( <form action={action}> <div> <label htmlFor="username">Username:</label> <input type="text" > <p>actions.ts:<br> </p> <pre class="brush:php;toolbar:false">"use server"; import { z } from "zod"; const SignUpSchema = z.object({ username: z.string(), password: z .string() .min(8, { message: "Be at least 8 characters long" }) .regex(/[a-zA-Z]/, { message: "Contain at least one letter." }) .regex(/[0-9]/, { message: "Contain at least one number." }) .regex(/[^a-zA-Z0-9]/, { message: "Contain at least one special character.", }) .trim(), }); export type SignUpActionState = { username?: string; password?: string; errors?: { username?: string[]; password?: string[]; }; }; export async function signUp( _prevState: SignUpActionState, form: FormData ): Promise<SignUpActionState> { const username = form.get("username") as string; const password = form.get("password") as string; const validatedFields = SignUpSchema.safeParse({ username, password, }); if (!validatedFields.success) { return { username, password, errors: validatedFields.error.flatten().fieldErrors, }; } // process validated form inputs here return { username, password }; }
useActionState also returns an isPending property (example) that indicates whether the server action's promise is still resolving.
Reference isPending to temporarily disable form elements, such as a submit button, to prevent users from clicking it multiple times in quick succession before the ongoing action has completed.
If you’re familiar with useFormAction and useFormStatus, you’ll find useActionState quite similar.
Essentially, it combines the functionality of both hooks and is renamed to reflect that server actions aren't just for forms (you can also use useActionState with buttons and other elements.)
Keep in mind that useFormStatus is deprecated as of Next.js 15, so you should import useActionState moving forward.
The above is the detailed content of Learn useActionState quickly with an example (Next.js. For more information, please follow other related articles on the PHP Chinese website!