safe-action-hooks

Use when executing next-safe-action actions from React client components -- useAction, useOptimisticAction, handling status/callbacks (onSuccess/onError/onSettled), execute vs executeAsync, or optimistic UI updates

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "safe-action-hooks" with this command: npx skills add next-safe-action/skills/next-safe-action-skills-safe-action-hooks

next-safe-action React Hooks

Import

// Standard hooks
import { useAction, useOptimisticAction } from "next-safe-action/hooks";

// Deprecated — use React's useActionState directly instead
import { useStateAction } from "next-safe-action/stateful-hooks";

useAction — Quick Start

"use client";

import { useAction } from "next-safe-action/hooks";
import { createUser } from "@/app/actions";

export function CreateUserForm() {
  const { execute, result, status, isExecuting, isPending } = useAction(createUser, {
    onSuccess: ({ data }) => {
      console.log("User created:", data);
    },
    onError: ({ error }) => {
      console.error("Failed:", error.serverError);
    },
  });

  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      const formData = new FormData(e.currentTarget);
      execute({ name: formData.get("name") as string });
    }}>
      <input name="name" required />
      <button type="submit" disabled={isPending}>
        {isPending ? "Creating..." : "Create User"}
      </button>
      {result.serverError && <p className="error">{result.serverError}</p>}
      {result.data && <p className="success">Created: {result.data.id}</p>}
    </form>
  );
}

useOptimisticAction — Quick Start

"use client";

import { useOptimisticAction } from "next-safe-action/hooks";
import { toggleTodo } from "@/app/actions";

export function TodoItem({ todo }: { todo: Todo }) {
  const { execute, optimisticState } = useOptimisticAction(toggleTodo, {
    currentState: todo,
    updateFn: (state, input) => ({
      ...state,
      completed: !state.completed,
    }),
  });

  return (
    <label>
      <input
        type="checkbox"
        checked={optimisticState.completed}
        onChange={() => execute({ todoId: todo.id })}
      />
      {todo.title}
    </label>
  );
}

Return Value

Both useAction and useOptimisticAction return:

PropertyTypeDescription
execute(input)(input) => voidFire-and-forget execution
executeAsync(input)(input) => Promise<Result>Returns a promise with the result
inputInput | undefinedLast input passed to execute
resultSafeActionResultLast action result ({ data?, serverError?, validationErrors? })
reset()() => voidResets all state to initial values
statusHookActionStatusCurrent status string
isIdlebooleanNo execution has started yet
isExecutingbooleanAction promise is pending
isTransitioningbooleanReact transition is pending
isPendingbooleanisExecuting || isTransitioning
hasSucceededbooleanLast execution returned data
hasErroredbooleanLast execution had an error
hasNavigatedbooleanLast execution triggered a navigation

useOptimisticAction additionally returns: | optimisticState | State | The optimistically-updated state |

Supporting Docs

Anti-Patterns

// BAD: Using executeAsync without try/catch when navigation errors are possible
const handleClick = async () => {
  const result = await executeAsync({ id }); // Throws on redirect!
  showToast(result.data);
};

// GOOD: Wrap executeAsync in try/catch
const handleClick = async () => {
  try {
    const result = await executeAsync({ id });
    showToast(result.data);
  } catch (e) {
    // Navigation errors (redirect, notFound) are re-thrown
    // They'll be handled by Next.js — just let them propagate
    throw e;
  }
};

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

safe-action-client

No summary provided by upstream source.

Repository SourceNeeds Review
General

safe-action-validation-errors

No summary provided by upstream source.

Repository SourceNeeds Review
General

safe-action-testing

No summary provided by upstream source.

Repository SourceNeeds Review
General

safe-action-middleware

No summary provided by upstream source.

Repository SourceNeeds Review