FormMessage не отображает ошибку проверки zod - Shadcn, Zod, response-hook-form, Next.js

У меня возникли проблемы с отображением ошибки проверки zod в FormMessage. Я следил за документацией shadcn по форме и вводу и делал все то же самое, но не могу понять, почему это не работает.

У меня есть этот компонент ввода формы (сделано так, чтобы его можно было использовать повторно)

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>
      )}
    />
  );
};

Схема зода следующая

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: "",
    },
  });

И форма используется вот так

<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>

Под каждым вводом должны отображаться ошибки проверки, если значения не такие, как они должны быть основаны на схеме zod, но ничего не происходит.

Вот ссылка на песочницу кода, которая воспроизводит проблемы. https://codesandbox.io/p/devbox/sharp-jasper-z6c4gz?file=%2Fapp%2Fpage.tsx%3A15%2C6

Я попробовал переустановить пакеты реакции-хука-формы и zod и понизить версию, но ничего не помогло. Я видел, что ошибки формы соответствуют ожиданиям в определении схемы, но сообщение об ошибке не передается в FormMessage из компонента FormInput.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
387
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вот решение вашей проблемы. Вы делаете что-то не так, если уместно использовать это слово.

Почему вы разрушаете форму и состояние формы, это выглядит ненужным и повторяющимся. Вы разрушаете его, чтобы создать новый объект, разве состояние формы уже не является объектом. formState уже существует как объект внутри объекта формы.

form = {{
        ...loginForm,
        formState: {
          ...loginForm.formState,
          isSubmitting: loginForm.formState.isSubmitting,
        },
      }}

Я заменил это на это

form = {loginForm}

Вот и все. Вы можете найти мое решение здесь, на codeandbox. https://codesandbox.io/p/devbox/sharp-jasper-forked-9dksfm

вы не используете это правильно:

const loginForm = useForm<z.infer<typeof loginViewFormSchema>>({
    resolver: zodResolver(loginViewFormSchema),
    defaultValues: {
      email: "",
      password: "",
    },
  });

вы передаете loginForm каждому компоненту FormInput как props. это тоже имеет свойство errors. в вашем компоненте FormInput:

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>
      )}
    />
  );
};  
FormInput.displayName = "FormInput";

тебе стоит добавить это в FormInput

  {props.error && <span>{error.message}</span>}

Другие вопросы по теме