I have some troubles with zod validation error displaying in the FormMessage. I've been following the shadcn documentation on form and input and I've done everything the same, but I can't seem to figure it out why this is not working.
I have this form-input component (did it so that it can be reused)
export const FormInput = <T extends FieldValues>(
props: FormElementProps<T>
) => {
return (
<FormField
control={props.form.control}
name={props.name}
render={({ field }) => (
<FormItem>
{props.label && <FormLabel>{props.label}</FormLabel>}
<FormControl>
<Input
{...field}
type={props.type}
disabled={props.disabled}
placeholder={props.placeholder}
/>
</FormControl>
{props.description && (
<FormDescription>{props.description}</FormDescription>
)}
<FormMessage />
</FormItem>
)}
/>
);
};
The zod schema is the following
export const loginViewFormSchema = z.object({
email: z.string().email({ message: "Email is required" }),
password: z.string().min(1, {
message: "Password is required",
}),
});
const loginForm = useForm<z.infer<typeof loginViewFormSchema>>({
resolver: zodResolver(loginViewFormSchema),
defaultValues: {
email: "",
password: "",
},
});
And the form is used like this
<Form {...props.form}>
<form
onSubmit={handleSubmit(formSubmitHandler)}
className="flex flex-col space-y-2"
>
<FormInput
form={props.form}
label="Email"
name="email"
disabled={formState.isSubmitting}
/>
<FormInput
form={props.form}
label="Password"
name="password"
type="password"
disabled={formState.isSubmitting}
/>
<Button type="submit" disabled={formState.isSubmitting}>
{formState.isSubmitting && (
<Icons.spinner className="w-4 h-4 mr-2 animate-spin" />
)}
Sign In
</Button>
<Button type="button" variant="link" onClick={onClickForgotPassword}>
Having trouble signing in?
</Button>
</form>
</Form>
There should be validation errors displayed under each input if the values are not as they should be based on the zod schema, but nothing happens
Here is a link to a code sandbox which reproduces the problems https://codesandbox.io/p/devbox/sharp-jasper-z6c4gz?file=%2Fapp%2Fpage.tsx%3A15%2C6
I tried reinstalling the react-hook-form and zod packages and downgrading, but nothing worked. I've seen that the form errors are as expected per the schema definition, but the error message is not passed to the FormMessage from the FormInput component.
Here is the solution to your issue. You are not doing something right, if that's the right word to use.
Why are you destructing the form and form state, it's look unnecessary and repetitive. You are destructing it to create a new object, isn't the form state an object already. formState already exist as an object inside the form object.
form={{
...loginForm,
formState: {
...loginForm.formState,
isSubmitting: loginForm.formState.isSubmitting,
},
}}
I replaced it with this
form={loginForm}
That's it. You can find my solution here on codesandbox https://codesandbox.io/p/devbox/sharp-jasper-forked-9dksfm