1

I have a field array where I have an input field for which I have set some validation rules like required and minLength.
I would like to when a new field is appended to have immediate validation on this fields. But, that is not happening, even when I append empty fields, errors stay undefined for those input fields:

function App() {
  const useFormMethods = useForm({
    defaultValues: {
      test: [{ firstName: "Bill", lastName: "Luo" }]
    },
    mode: "onChange"
  });
  const { fields, append, remove } = useFieldArray({
    control: useFormMethods.control,
    name: "test",
    rules: {
      minLength: 4
    }
  });

  const onSubmit = (data) => console.log("data", data);

  return (
    <FormProvider {...useFormMethods}>
      <form onSubmit={useFormMethods.handleSubmit(onSubmit)}>
        <h1>Field Array </h1>
        <span className="counter">Render Count: {renderCount}</span>
        <ul>
          {fields.map((item, index) => {
            return (
              <li key={item.id}>
                <FormControlledInput name={`test.${index}.firstName`} />
                <FormControlledInput name={`test.${index}.lastName`} />
                <button type="button" onClick={() => remove(index)}>
                  Delete
                </button>
              </li>
            );
          })}
        </ul>
        <section>
          <button
            type="button"
            onClick={() => {
              append({ firstName: "", lastName: "" });
            }}
          >
            append
          </button>
        </section>

        <input type="submit" />
      </form>
    </FormProvider>
  );
}

This is the controlled input that needs validation:

export const FormControlledInput = ({ name }) => {
  const {
    control,
    formState: { errors }
  } = useFormContext();

  const { field, fieldState } = useController({
    name,
    control,
    rules: { required: true }
  });

  console.log(`fieldState error: `, fieldState.error);
  console.log(`formState errors: `, errors);

  return <input onChange={field.onChange} value={field.value} />;
};

You can check the working codesandbox example here. What do I need to do to have it validate on each change?

1 Answer 1

0

The append method you're using to add the field to the array is asynchronous, as is the trigger method to perform the validation, so there's a race condition that is causing the validation to be triggered before the field is registered with the form. You can just await that function result before triggering a revalidate when an array field is added.

          <button
            type="button"
            onClick={async () => {
              await append({ firstName: "", lastName: "" });
              useFormMethods.trigger();
            }}
          >
            append
          </button>

I forked your CSB here. I also added a useEffect hook that will trigger validation when the component is mounted.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.