-
-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
handleSubmit
does not always mark all fields as touched
#1360
Comments
#1355 appears to be a related issue, but I would like confirmation that this truly is intended behaviour. |
Shoff brought up an example with field validators. It's related to the early return that causes this issue, but is not related to the https://stackblitz.com/edit/tanstack-form-ew4q42pd?file=src%2Findex.tsx&preset=node |
Can confirm that using submission attempts allows the correct behavior for me: "use client";
import type { AnyFieldApi, StandardSchemaV1Issue } from "@tanstack/react-form";
import { useStore } from "@tanstack/react-form";
/**
* Displays the status of a field.
*
* The Standard Schema is compatible with Standard Schema validation libraries such as Zod.
*
* @see https://github.com/standard-schema/standard-schema
*/
export function FieldStatus({ field }: { field: AnyFieldApi }) {
const submissionAttempts = useStore(field.form.store, state => state.submissionAttempts)
let errorMessage = "";
const validate = submissionAttempts > 0 || field.state.meta.isTouched;
if (validate && field.state.meta.errors.length > 0) {
const errors = field.state.meta.errors as StandardSchemaV1Issue[];
errorMessage = errors.map((error) => error.message).join(", ");
}
return (
<>
{errorMessage && (
<div className="mt-1 text-sm text-red-600">{errorMessage}</div>
)}
{field.state.meta.isValidating && (
<div className="mt-1 text-sm text-gray-600">Validating...</div>
)}
</>
);
} const form = useForm({
defaultValues: {
myStuffs: '...',
},
validators: {
onChangeAsync: myValidator,
onChangeAsyncDebounceMs: 150,
},
onSubmit: async ({ value }) => {
mutation.reset();
await mutation.mutateAsync({
myStuffs: '...'
});
},
}); |
Describe the bug
When calling
<useForm>.handleSubmit()
or<useAppForm>.handleSubmit()
, all fields being touched is not consistent when used with form-level validators.That is because of an early return statement that is sensible in theory, but has problems in edge cases.
Example
I have two fields,
requiredName
andoptional
. When using a standard schema and passing it to<useForm>
asonChange
validator, it will validaterequiredName
when changingoptional
. That makes complete sense.However, that means that
canSubmit
can become false even if no required field has ever been touched. This results in submission handling returning early without marking all the fields as touched.The Stackblitz contains examples of this behaviour.
Use case
My use case is that I only show errors on touched fields. This prevents multiple errors to show up when modifying an optional field (due to schema validation). With
canSubmit = false
, they will now be stuck in an error state but cannot show it due to being untouched.Is this intended behaviour?
Your minimal, reproducible example
https://stackblitz.com/edit/vitejs-vite-od8bfy6y?file=src%2FApp.tsx
Steps to reproduce
Expected:
isTouched
Actual:
onChange
oronBlur
don't mark field 1 asisTouched
onSubmit
marks field 1 asisTouched
onSubmit
and any of the other two, field 1 will not beisTouched
Expected behavior
As user, I expect
isTouched
to be true for all fields when handling the submission, independent from which validator you used.How often does this bug happen?
None
Screenshots or Videos
No response
Platform
TanStack Form adapter
react-form
TanStack Form version
v1.2.1
TypeScript version
v5.7.2
Additional context
For anyone with the same problem, you can access
submissionAttempts
withuseStore(field.form.store, state => state.submissionAttempts)
. This allows you to check if a submission has happened before, overriding any touched condition in your logic.This state is accessible in both the callback as well as field context.
The text was updated successfully, but these errors were encountered: