Using react-hook-form useFieldArray with useForm and defaultValues
Another item in my “react-hook-forms is confusing” list. Not sure how many items I need before I switch perspective from “I just don’t grok react-hook-forms yet” to “it’s not me, it’s you”.
Anyway, I was trying to use useFieldArray
to create a dynamic form. I was also using useForm
to see some default values, which is standard practice AFAIK.
const data = {
timezone: "New Zealand",
emails: ["craig@example.com"],
};
const { control } = useForm({ defaultValues: data });
timezone
is a selector, while emails
is dynamic form element that lets the user add more email addresses. The docs for useFieldArray
give this example that I’ve trimmed a little.
const { control } = useForm();
useFieldArray({
control,
name: "test", // unique name for your Field Array
});
What wasn’t obvious from the docs is that if you’re supplying defaultValues
to useForm
then your control
is typed with the shape of defaultValues
, and useFieldArray
picks that up and requires name
to be a property of defaultValues
. Great, that’s helpful - I want to use the emails
property of my defaultValues
useFieldArray({ control, name: "emails" });
Unfortunately this makes Typescript complain:
Type 'string' is not assignable to type 'never'.ts(2322)
fieldArray.d.ts(6, 5): The expected type comes from property 'name' which is declared here on type 'UseFieldArrayProps<{ timezone: string; emails: string[]; }, never, "id">'
The problem is that emails
is a flat array of strings, and useFieldArray
requires it to be an array of objects. So I need to transform emails
to be an array of objects
const data = {
timezone: "New Zealand",
emails: [{ address: "craig@example.com" }],
};
and now I can do
useFieldArray({
control,
name: "emails",
});
To be fair, the docs “Rules” section says
Does not support flat field array.
But that is pretty cryptic and it’s not obvious that the type error is connected to that rule.
Hopefully this helps someone!