Submission Handling
ts
const form = new FormApi({
initialValue: { email: "", password: "" },
onSubmit: async (form) => {
await login(form.value);
},
onSubmitError: (form, error) => {
toast.error("Failed to log in");
},
});
formEl.addEventListener("submit", form.handleSubmit);tsx
function LoginForm() {
const form = useForm({
initialValue: { email: "", password: "" },
onSubmit: async (form) => {
await login(form.value);
},
onSubmitError: (form, error) => {
toast.error("Failed to log in");
},
});
return <form onSubmit={form.handleSubmit}>{/* ... */}</form>;
}handleSubmit:
- Waits out any pending validation.
- If the form is invalid, marks it
touched(so errors on never-blurred fields become visible) and callsonSubmitInvalid, then returns. - Otherwise sets
submittingtotrue, callsonSubmit, and falls back toonSubmitErrorif it throws/rejects.
A no-op on a re-entrant call while already submitting. The event parameter is optional and used only for preventDefault(), so the same call works from a React Native onPress, any caller with no event, or a web <form onSubmit> as shown above.
Disabling the submit button while submitting
submitting (and dirty, for a "nothing to save" state) are ordinary reactive state, so gate the button like any other field property:
ts
form.subscribe(() => {
submitButton.disabled = form.submitting || !form.dirty;
});tsx
<Watch api={form} select={(f) => [f.submitting, f.dirty] as const}>
{(form, [submitting, dirty]) => (
<button type="submit" disabled={submitting || !dirty}>
Save
</button>
)}
</Watch>;What's next
FormApi— full reference on JSR