useNexusFormAction
useNexusFormAction
is a client-side hook that simplifies using a Server Action as an HTML form action. It’s built on top of the standard React useFormState
hook and adds pending/success/error states and lifecycle callbacks.
Import
import { useNexusFormAction } from 'next-nexus/client';
Core Concepts
When to Use
Use this hook when you want to progressively enhance an HTML <form>
. It allows a form to be submitted via a Server Action, providing a great user experience with minimal client-side JavaScript. It’s the recommended way to handle form submissions with Server Actions in Next.js.
How It Works
You pass a Server Action to the hook. It returns a formAction
function that you pass directly to the <form action={formAction}>
attribute. The hook manages the form’s state, including pending status and the result returned from the Server Action.
Signature
Parameters
serverAction
:(formData: FormData) => Promise<TResult>
— The Server Action to be executed on form submission. It automatically receives theFormData
.options?
: An optional object to configure lifecycle callbacks.
Return Value
An object containing:
formAction
:(payload: FormData) => void
— The function to pass to the<form>
action
attribute.isPending
:boolean
isSuccess
:boolean
isError
:boolean
result
:TResult | undefined
error
:Error | null
reset
:() => void
Options
onStart?
:(formData: FormData) => void | Promise<void>
onSuccess?
:(result: TResult, formData: FormData) => void | Promise<void>
onError?
:(error: Error, formData: FormData) => void | Promise<void>
onSettled?
:(result?: TResult, error?: Error, formData: FormData) => void | Promise<void>
Example
This example shows a simple form that uses a Server Action to create a new product. The isPending
state is used to disable the submit button during submission.
'use client'
import { useNexusFormAction } from 'next-nexus/client'
import { revalidateServerTags } from 'next-nexus'
import { revalidateClientTags } from 'next-nexus/client'
// Assume this action is in a separate file, e.g., app/actions.ts
async function createProductAction(formData: FormData) {
'use server'
const name = formData.get('name') as string;
// ... database logic to create the product
await revalidateServerTags(['products']);
return { ok: true, productName: name };
}
export default function ProductForm() {
const { formAction, isPending, isSuccess, result } = useNexusFormAction(createProductAction, {
onSuccess: () => {
revalidateClientTags(['products']);
}
});
return (
<form action={formAction}>
<input name="name" placeholder="Product Name" required />
<button type="submit" disabled={isPending}>
{isPending ? 'Saving...' : 'Save'}
</button>
{isSuccess && <div>Product "{result?.productName}" saved!</div>}
</form>
);
}
See also