Creating recursive and dynamic forms with React Hook Form and TypeScript

JavaScript React

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:

If you want to learn the basics of React Hook Form instead, check out Building forms with React Hook Form and TypeScript

Dealing with arrays of inputs

Let’s start with defining an interface that describes the form values.

FriendsFormValues.tsx

Also, let’s create the basics of our form that uses the component. Thanks to doing that, we will be able to access the context of the form in the components we create later.

FriendsForm.tsx

We use SCSS modules to style all of the componentes in this article.

We initiate the form with simple values. Then, if the user clicks on the submit button, we log the values to the console.

useFriendsForm.tsx

Using the useFieldArray hook

In our form, we have the 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 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 to handle arrays of primitive values such as strings or numbers. Because of that, our property needs to be an array of objects.

The hook returns various useful objects and functions that allow us to interact with the array. In this application, we use the following:

  •  – an array of objects containing the default value of a particular element and an autogenerated id to use as a key,
  • – a function we use to add another element to our array,
  • – we can use this function to remove a particular element.

We can create a custom hook that uses all of the above functionalities.

useFriendsFormField.tsx

Now, we can create a component that takes advantage of all of the above functions.

FriendsFormField.tsx

Above, the most crucial part is the following where we use the autogenerated and the function:

Please notice that we use  instead of . This started to be the required approach since React Hook Form v7.

After doing all of the above, we end up with the following form:

Working with recursive data structures

So far, we’ve been working with a simple array of objects. Let’s make it a bit more interesting by making our data structure recursive.

If you want to know more about recursion, check out Using recursion to traverse data structures. Execution context and the call stack

FriendsFormValues.tsx

Let’s modify our 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:

  • an empty string,
  • ,
  • ,
  • ,
FriendsFormField.tsx

Unfortunately, React Hook Form currently does not handle circular references in the data well with TypeScript as stated in the official documentation. Because of that, we declare our again without the circular references.

It is possible that React Hook Form 8 will improve the above situation.

useFriendsFormField.tsx

Above, we combine the current prefix with “name” and “friends”. For example, if our prefix is , we get and .

We now have everything we need to define the component.

FriendsFormField.tsx

The crucial thing is that renders recursively. To generate a new prefix, we combine the current prefix with :

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 hook.

While React Hook Form was created just three years ago, it quickly became popular and recently caught up with Formik, its main competitor.

If you want to know how to build the above form with Formik, check out Dynamic and recursive forms with Formik and TypeScript

Also, React Hook Form seems to be more actively maintained, which can be a critical factor when choosing a suitable library for a project.

All of the above make the React Hook Form a fitting solution for form in our new React projects, even when dealing with recursive data structures.

Subscribe
Notify of
guest
4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
natalia
natalia
2 years ago

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)

Adam
Adam
2 years ago

Great one! I have been struggling with putting something similar together

Do you have CSS styles used in this module available somewhere?

ris
ris
1 month ago

anyone have a codesandbox example?