Create Forms in React Without Stress

The simple way for managing validation, errors, list of modified fields, and more

Inna Sinicka
Better Programming

--

Photo by Tyler Nix on Unsplash

Honestly, there are many ways how you can manage a form’s state. We have a lot of options nowadays. Formik, React Hook Form, and React Final Form are the most popular.

Oh, and you can make your custom hook. The most challenging part here is choosing the right option for your project.

My Story

A couple of years ago, I was investigating managing forms in React, looking for the best solution for me. I wanted to find a simple and beautiful way to manage validation and errors, keep a list of visited fields, and more.

So what did it do? I created my custom hook!

Yes, I love coding, and I love creating my solutions. It is a simple hook that uses userReducer underneath to manage the form’s state. Changes were updated on each keystroke in the form (we all know it is normal to React behaviour).

I didn’t have any fancy validation there, data was checked only on submit, and it all worked well, but…

Problems

Performance! I did not feel it at the beginning. I used my hook in many forms, and everything was great, but my forms grew; I had big nested objects, so I had to do some magic with useMemo, useCalback, and correct composition, and that helped, but…

I realised my solution was too simple. I needed much more. I wanted to quickly detect if any changes were made in the form, which fields were changed, and more. I probably could improve my hook and make it more “clever,” but it would take me much more effort and time. If there were no existing solutions, then fine, but that was not the case.

Don’t get me wrong. I am not talking about elementary forms, where you have one or two input fields and one button. You can easily live without any library.

I understood that I didn’t want to waste my time on fixing these problems; I just wanted to find a library that would do all that things and should not provoke rerendering on every change in a form.

And I started learning existing solutions.

Looking for an Answer

At that moment, the most popular was Formik. If we look at the official documentation now, we can see that it is still one of the recommended ways.

If you’re looking for a complete solution, including validation, keeping track of the visited fields, and handling form submission, Formik is one of the popular choices. However, it is built on the same principles of controlled components and managing state — so don’t neglect to learn them.

But as I have mentioned before, I didn’t want to rerender my form on each change. After reading documentation and experimenting, I chose React Hook Form.

Why React Hook Form?

  1. Using useRef improves performance. You can read about it in the official documentation.
  2. You can use Yup for validation.
  3. Excellent documentation with a lot of examples.
  4. You can register uncontrolled components or use controlled with Controller from react-hook-form, which allows you to use components from libraries like MatetialUi, AntTd, FluentUI, and others.
  5. Library uses the useContext hook, so you can pass methods to deeply nested children.
  6. If you feel comfortable with hooks, RHF syntax will look very familiar and understandable.

I felt the difference when I started using this library and saw it with React Profiler. It is helpful to see how often your components are rerendering and why. Sometimes it can help to solve performance issues.

Using Yup

I had mentioned before that I needed to manage validation, so I used Yup for it. It is a fantastic way of validating data because you can use it independently or with other libraries for managing the state.

It is easy to use yup for defining validation; you have a lot of different types, and you can describe dependencies and your validation rules. In my example, I have filed “surname,” which is required when the field’s title value is “Test.” Look at this example, and you will see how simple it is to use Yup:

Using React Hook Form

Using components from libraries like FluentUI, MaterialUI or others is helpful to have the option to use controlled components. Yes, I didn’t want to use them but React Hook Form allows me to use controlled components, minimizing rendering. Unfortunately, I can’t use some of FluentUI components uncontrolled, so it is awesome that RHF is helping with optimizing performance.

OK, but how to use this library?

First, we need to install two packages: npm install react-hook-form yup. We can pass default values and say how often we want to validate our form.

Then we need to decide what type of components we will use. We have two options here:

  1. Register uncontrolled components
  2. Use wrapper called Controller for controlled components

For the second option, you will need to wrap your component with a Controller from RHF. Here is my example with TextField from the FluentUI library.

The best is that we can combine two options and use both ways in one form if we need. Here is my example with controlled components:

Here is the final result — quickly and easily.

That’s all about managing the form’s state in React with React Hook Form and Yup. I hope that these libraries will help you too.

--

--

Frontend developer who writes all about React, ways to increase productivity, focus and how to be a happy programmer.