How to stop bleeding of validation errors into a seconde field connected with onChangeListenTo #2048
-
|
Hello, I have the following issue. I am using zod form level validation and have two date input fields. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
The issue is that when you use form-level Zod validation combined with field-level The root of the problem is that Fix: Separate form-level and field-level concerns Don't mix form-level Zod schema validation with field-level Option A: All field-level (recommended) export default function Test() {
const form = useAppForm({
defaultValues: { a: '', b: '' },
});
return (
<div>
<form.AppField
name="a"
validators={{
onChange: ({ value }) => {
if (!value) return 'Date is required'
if (isNaN(Date.parse(value))) return 'Invalid date'
return undefined
},
}}
children={(field) => <field.InputField label="A" inputType="date" />}
/>
<form.AppField
name="b"
validators={{
onChangeListenTo: ['a'],
onChange: ({ value, fieldApi }) => {
const a = fieldApi.form.getFieldValue('a')
if (value && a && parseISO(value) < parseISO(a)) {
return 'B must be after A'
}
return undefined
},
}}
children={(field) => <field.InputField label="B" inputType="date" />}
/>
</div>
);
}Option B: Form-level Zod only If you want to keep Zod for everything, use const formSchema = z.object({
a: z.iso.date(),
b: z.union([z.iso.date(), z.literal('')]),
}).superRefine((data, ctx) => {
if (data.a && data.b && parseISO(data.b) < parseISO(data.a)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'B must be after A',
path: ['b'],
})
}
})The key insight: mixing form-level schema validation with field-level |
Beta Was this translation helpful? Give feedback.
The issue is that when you use form-level Zod validation combined with field-level
onChangeListenTo, errors from the Zod schema get mapped to fields based on the Zod path — and when fieldais empty/invalid, Zod's error foracan end up bleeding into fieldbbecause the form-level validator runs for both fields.The root of the problem is that
z.iso.date()on fieldaproduces an error with path['a'], but because yourbfield listens toaviaonChangeListenTo: ['a'], it also re-validates whenachanges. The form-level validator runs and its errors are distributed across fields — sometimes incorrectly.Fix: Separate form-level and field-level concerns
Don't mix form-level Zod schema valida…