React Hook Form is a popular library that helps us deal with forms and keep their code consistent across the whole application. In this article, we look into how to allow the user to shape the form to some extent and create data structures that are recursive. In the end, we get the following form:
Let’s start with defining an interface that describes the form values.
FriendsFormValues.tsx
1
2
3
4
5
6
interfaceFriendsFormValues{
name:string;
friends:{name:string}[];
}
export defaultFriendsFormValues;
Also, let’s create the basics of our form that uses the
<FormProvider/> component. Thanks to doing that, we will be able to access the context of the form in the components we create later.
In our form, we have the
friends array. In our case, we want users to be able to add, modify, and remove elements from this array. Fortunately, React Hook Form has a hook designed just for this purpose.
Above, we use the
control object that contains methods for registering components into React Hook Form. We also provide the name of the field we want to handle.
React Hook Form currently does not support using
useFieldArray to handle arrays of primitive values such as strings or numbers. Because of that, our
friends property needs to be an array of objects.
The
useFieldArray hook returns various useful objects and functions that allow us to interact with the array. In this application, we use the following:
fields – an array of objects containing the default value of a particular element and an autogenerated id to use as a key,
append – a function we use to add another element to our array,
remove – we can use this function to remove a particular element.
We can create a custom hook that uses all of the above functionalities.
Let’s modify our
FriendsFormField component to accept a prefix so that we can keep track of how deep we are in our form. Some of its possible values are:
Above, we combine the current prefix with “name” and “friends”. For example, if our prefix is
friends[0].friends[1]., we get
friends[0].friends[1].name and
friends[0].friends[1].friends.
We now have everything we need to define the
FriendsFormField component.
The crucial thing is that
FriendsFormField renders
FriendsFormField recursively. To generate a new prefix, we combine the current prefix with
friends.${index}.:
Thanks to the above approach, we end up with the following form:
Summary
In this article, we’ve managed to create dynamic forms that deal with recursive data structures using React Hook Form and TypeScript. To do that, we had to learn about the
useFieldArray hook.
While React Hook Form was created just three years ago, it quickly became popular and recently caught up with Formik, its main competitor.
Very basic example, I am looking for an example that adds “a set of columns per row” e.g. add friend (first-name, last-name, age)
Feel free to add more properties to the FriendsFormValues interface.
Great one! I have been struggling with putting something similar together
Do you have CSS styles used in this module available somewhere?
anyone have a codesandbox example?