skip to Main Content

I’m using React Hook Form with dynamic fields for teams. While the validation works and displays errors correctly upon submit, the error messages don’t disappear when I correct the input. Here’s the relevant code:

const formSchema = z.object({
  name: z.string().min(1, 'Please enter a name'),
  team: z.array(
    z.object({
      name: z.string().min(1, 'Please enter a name'),
      role: z.string().min(1, 'Please enter a role'),
    })
  ).max(10).optional(),
});

const formMethods = useForm<FormValues>({
    defaultValues: {
      ...defaultValues,
    } as FormValues,
    validationResolver,
    validationContext: formSchema,
  });

const {
    fields: teamFields,
    append: appendTeamFields,
    remove: removeTeamFields,
  } = useFieldArray({ name: 'team', control: formMethods.control });

Temeplate

{teamFields.map((_, idx) => (
  <div key={idx}>
    <input
      name={`team[${idx}].name`}
      ref={formMethods.register(`team[${idx}].name`)}
    />
    <input
      name={`team[${idx}].role`}
      ref={formMethods.register(`team[${idx}].role`)}
    />
    {formMethods.errors?.team?.[idx]?.name && 
      <span>
        {formMethods.errors.team[idx].name.message}
      </span>
    }
    {formMethods.errors?.team?.[idx]?.role && 
      <span>
        {formMethods.errors.team[idx].role.message}
      </span>
    }
  </div>
))}

Im using react-hook-form": "^5.7.2", If I submit with errors, they display correctly. After correcting the input, the error messages remain displayed until I submit again.

2

Answers


  1. What version of react-hook-form is this? I can’t see that it returns errors directly in formMethods. They are inside formState.

    It is explained in the documentation when the validation get triggered. https://react-hook-form.com/docs/useform#mode . It is on submit. You can change it to onChange

    Login or Signup to reply.
  2. I think you are missing to write an ".", on registration of you team fields.

    {teamFields.map((_, idx) => (
      <div key={idx}>
        <input
          name={`team.${idx}.name`}
          ref={formMethods.register(`team.${idx}.name`)}
        />
        <input
          name={`team.${idx}.role`}
          ref={formMethods.register(`team.${idx}.role`)}
        />
        {formMethods.errors?.team?.[idx]?.name && 
          <span>
            {formMethods.errors.team[idx].name.message}
          </span>
        }
        {formMethods.errors?.team?.[idx]?.role && 
          <span>
            {formMethods.errors.team[idx].role.message}
          </span>
        }
      </div>
    ))}
    

    I think that you could omit the "name" parameter of the inputs fields since you are using the "register" function. I think it injects the name parameter by default.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search