Skip to main content



useAction waits for the action to finish execution before returning the result. If you need to perform optimistic updates, use useOptimisticAction instead.

With this hook, you get full control of the action execution flow. Let's say, for instance, you want to change what's displayed by a component when a button is clicked.


  1. Define a new action called greetUser, that takes a name as input and returns a greeting:
const schema = z.object({
name: z.string(),

export const greetUser = action(schema, async ({ name }) => {
return { message: `Hello ${name}!` };
  1. In your Client Component, you can use it like this:
import { useAction } from "next-safe-action/hooks";
import { greetUser } from "@/app/greet-action";

export default function Greet() {
const [name, setName] = useState("");
const { execute, result } = useAction(greetUser);

return (
<input type="text" onChange={(e) => setName(} />
onClick={() => {
execute({ name });
Greet user
{ ? <p>{}</p> : null}

As you can see, here we display a greet message after the action is performed, if it succeeds.

useAction arguments

useAction has the following arguments:

safeActionSafeActionThis is the action that will be called when you use execute from hook's return object.
callbacks?HookCallbacksOptional callbacks. More information about them here.

useAction return object

useAction returns an object with the following properties:

execute(input: InferIn<S>) => voidAn action caller with no return. The input is the same as the safe action you passed to the hook.
resultHookResultWhen the action gets called via execute, this is the result object.
statusHookActionStatusThe action current status.
reset() => voidYou can programmatically reset the result object with this function.

Explore a working example here.