Skip to Content
Prism UI
Forms

Submission and Error Handling

Handling form submission and displaying validation errors, using real React Hook Form behavior.

Submission

usePrismForm returns React Hook Form's own handleSubmit, unmodified:

<form
  onSubmit={form.handleSubmit(
    (values) => {
      // values is typed as FormValues, and has already passed validation.
      submitToServer(values);
    },
    (errors) => {
      // optional: invoked instead, with the full RHF FieldErrors object, on a failed validation.
      console.log('validation failed', errors);
    },
  )}
>

form.formState.isSubmitting reflects a real, in-flight async submit the same way it would with plain React Hook Form, handleSubmit's first callback can be async and isSubmitting stays true until it resolves.

Error display

A field-level error reaches its component through the same field.error property described in Form Engine Overview, whether it came from rules, a Zod resolver, or a manually set error:

export function TextField({ field, label }: FieldComponentProps<string, { label: string }>) {
  return (
    <label>
      {label}
      <input
        value={field.value ?? ''}
        onChange={(e) => field.onChange(e.target.value)}
        onBlur={field.onBlur}
        aria-invalid={field.error !== undefined}
      />
      {field.error ? <span role="alert">{field.error}</span> : null}
    </label>
  );
}

There's no separate "Prism error state" to read, field.error is derived directly from RHF's own fieldState.error?.message for that field.

Setting a form-level error manually

Because usePrismForm returns the complete UseFormReturn, setError works exactly as in plain React Hook Form, useful for a server-side rejection a client schema can't predict:

try {
  await submitToServer(values);
} catch {
  form.setError('root', { message: 'Something went wrong. Please try again.' });
}

form.formState.errors.root?.message reads it back; this is not a Prism-specific mechanism, it's RHF's own root-level error slot.

Resetting after submission

form.handleSubmit((values) => {
  submitToServer(values);
  form.reset(); // restores defaultValues
});

form.reset(newDefaults) also works, exactly as in plain RHF, to reset to a different set of values.

On this page