T
TanStack2mo ago
rare-sapphire

form.state.isValid/ isFormValid / isFieldsValid is true, form.state.errors is empty, zod schema

Hello, I am trying to disable the save button of a form when the description field is empty. I guess I have to use either form.state.isValid or .isFormValid or isFieldsValid, any of the three options 😵‍💫 but they are always true, even when I see the zod validation error My form:
const form = useForm({
defaultValues: {
...
},
onSubmit: async ({ value: partFormData }) => {
try {
if (createPart) {
const { id, ...newPartData } = partFormData;
await onSave(newPartData);
} else {
await onSave(partFormData);
}
return { status: "success" };
} catch (error) {
const errorDescription = error instanceof Error ? error.message : "Error desconocido";
toast.error("Error al guardar el artículo", {
description: errorDescription,
});
return { status: "error", message: errorDescription };
}
},
});
const form = useForm({
defaultValues: {
...
},
onSubmit: async ({ value: partFormData }) => {
try {
if (createPart) {
const { id, ...newPartData } = partFormData;
await onSave(newPartData);
} else {
await onSave(partFormData);
}
return { status: "success" };
} catch (error) {
const errorDescription = error instanceof Error ? error.message : "Error desconocido";
toast.error("Error al guardar el artículo", {
description: errorDescription,
});
return { status: "error", message: errorDescription };
}
},
});
No description
8 Replies
rare-sapphire
rare-sapphireOP2mo ago
My component code:
<p>isValid: {form.state.isValid ? "true" : "false"}</p>
<p>isFormValid: {form.state.isFormValid ? "true" : "false"}</p>
<p>isFormValid: {form.state.isFieldsValid ? "true" : "false"}</p>
<p>Field errors: {JSON.stringify(form.state.fieldMeta.description?.errors)}</p>
<p>Form errors: {JSON.stringify(form.state.errors)}</p>
<div className="flex flex-col items-start gap-6 2xl:flex-row">
<div className="flex w-full flex-col gap-6 sm:grid sm:grid-cols-2">
<form.Field
name="description"
validators={{
onChange: z.string().min(1, "Campo obligatorio"),
}}
children={({ state, handleChange, handleBlur }) => (
<div className="space-y-2">
<Label htmlFor="description">Descripción</Label>
<Input
id="description"
value={state.value}
onChange={(e) => handleChange(e.target.value)}
onBlur={handleBlur}
errorMessage={state.meta.errors.at(0)?.message ?? ""}
/>
</div>
)}
/>
<p>isValid: {form.state.isValid ? "true" : "false"}</p>
<p>isFormValid: {form.state.isFormValid ? "true" : "false"}</p>
<p>isFormValid: {form.state.isFieldsValid ? "true" : "false"}</p>
<p>Field errors: {JSON.stringify(form.state.fieldMeta.description?.errors)}</p>
<p>Form errors: {JSON.stringify(form.state.errors)}</p>
<div className="flex flex-col items-start gap-6 2xl:flex-row">
<div className="flex w-full flex-col gap-6 sm:grid sm:grid-cols-2">
<form.Field
name="description"
validators={{
onChange: z.string().min(1, "Campo obligatorio"),
}}
children={({ state, handleChange, handleBlur }) => (
<div className="space-y-2">
<Label htmlFor="description">Descripción</Label>
<Input
id="description"
value={state.value}
onChange={(e) => handleChange(e.target.value)}
onBlur={handleBlur}
errorMessage={state.meta.errors.at(0)?.message ?? ""}
/>
</div>
)}
/>
rare-sapphire
rare-sapphire2mo ago
did you use Subscribe or useStore to ensure those values are actually reactive?
rare-sapphire
rare-sapphireOP2mo ago
No, I was not 🥸 Even if I do const errors = useStore(form.store, (state) => state.errors); , the component is not rerendered when the error is shown ...
rare-sapphire
rare-sapphire2mo ago
could you create a minimal example of this happening? On stackblitz, or a github project / gist, codesandbox? It can help figure out what part may be broken, or what section is wrong
rare-sapphire
rare-sapphireOP2mo ago
I am passing the form fields as a children to another component... I will try to pass the form variable as a prop and use <form.Subscribe> inside the component to disable the submit button as shown in the official example, let me see ... (I guess passing the form as a prop is fine, right?)
rare-sapphire
rare-sapphire2mo ago
it‘s not encouraged, but it shouldn‘t break anything since the form hook itself is stable
rare-sapphire
rare-sapphireOP2mo ago
Using form.Subscribe worked like a charm! I have no time to make try to search whether there is a bug, my code is quiite long and interconnected, I can not paste it in a meaninful way, sorry ... And thanks for the help!
rare-sapphire
rare-sapphire2mo ago
subscribe is a useStore call internally, so that‘s strange

Did you find this page helpful?