How to enabled using useWatch & useFieldArray for array property in react-form-hook

Neat/weird tricks using react-form-hook

I recently found out that useWatch & useFieldArray hook is not something that can be used for any array parameters when using react-form-hook. This caused me to be confused as I was not aware what are the other requirements needed in order to use useWatch & useFieldArray hook. After searching around in stack overflow, I found out…

It must be an array of object.

Imagine this, you have two parameters that are array. But somehow you can only use useWatch & useFieldArray for one of the parameters and not the other. Why is that?

const { handleSubmit, control, watch, getValues, setValue } = useForm<SomeForm>({
  mode: 'onBlur',
  reValidateMode: 'onBlur',
  defaultValues: {
    quantity: [1, 2, 3], // can't use useWatch & useFieldArray
    userInfo: [{id: 1, name: "John"}, {id: 2, name: "Amelia"}] // can use useWatch & useFieldArray
  },
  shouldFocusError: true,
});

// this will throw error
const { fields, remove, append } = useFieldArray({
  name: "quantity",
  control,
});

// this will not throw error
const { fields, remove, append } = useFieldArray({
  name: "userInfo",
  control,
});

You may have encountered similar error messages like Type '"quantity"' is not assignable to type '"UserInfo". Unfortunately, I am not here to tell you what I understand as the error message wasn’t really helpful. It didn’t tells us what is the main issue. The error message is basically just saying it is expecting quantity to have the same type/property as UserInfo. But it doesn’t make any sense.

Fortunately, there is way to solve this. The only way to enable quantity parameter to be able to use both hooks is by making it as an array of object.

const { handleSubmit, control, watch, getValues, setValue } = useForm<SomeForm>({
  mode: 'onBlur',
  reValidateMode: 'onBlur',
  defaultValues: {
    quantity: [{content: 1}, {content: 2}], // now it can use useWatch & useFieldArray
    userInfo: [{id: 1, name: "John"}, {id: 2, name: "Amelia"}] // can use useWatch & useFieldArray
  },
  shouldFocusError: true,
});

// Now, it will work!
const { fields, remove, append } = useFieldArray({
  name: "quantity",
  control,
});

Resources