Form Handling Without Suffering Using React Hook Form
/ 6 min read
Form is an important part of the web that allows users to submit data to the server.
It is the technology that allows us to book hotels for our next holiday or fill out our taxes.
Some industries such as banking, finance and taxes can have very complicated forms.
In this post I want to show you the problems handling forms with React and how React Hook Form solves this.
How hard is it to build a simple form in React?
Let me show you an example of a simple sign up form.
Here are the required validations for this form:
- Username must be between 3 to 8 characters, alphabets only.
- Password must be between 5 to 10 characters.
- Confirm Password must be the same as password.
How do you build this feature with React?
1. Define the components
Here’s a simplified version of how the components are defined.
Each text field has a label, the actual input element and also a div to show error message.
2. Handle input events
In order to get the user typed value, we can either:
useRef
to capture the input ref- or
useState
to store the user input every time the value changes.
I’m gonna go with the latter approach.
We’re going to need three states.
Aside from creating states to store the input data, we also need states to store the error message.
And we’re going to assign the states to the input fields.
3. Validating and submitting the form
This is how we validate the form data and then send it to the server.
You can see the full code here.
Why is it a problem?
This code is okay if you only deal with forms once or twice in your app, but can feel tedious very quickly if you have to deal with 20 forms, or maybe just one but with dozens of fields.
The problem can get worse when the requirements are more complex:
- Users can add or remove up to 5 phone numbers.
- The form is split into multiple steps.
- Sometimes the form in the next steps become different depending on the user input.
- Some sections become mandatory if the users tick some boxes in the immigration form.
How React Hook Form solves this
There are a lot of solutions from the React community to handle forms.
The best one I like so far is using react-hook-form to handle the events, and Zod to handle the validations.
Let me give you a quick tour of how it works by building the same feature.
Don’t worry I’ll explain more details in the future posts if you’re interested.
Define the validations
First we define the fields and their validations of our forms.
You probably have an idea of what happened even if you don’t have any experience using Zod.
The .refine
part is a bit advanced, but in short it is a way to do a custom validation for the fields.
Add validations to the form
The next thing is using the validations we defined previously to the form.
useForm
will handle everything for us. All we need to do is to handle input events using register
method.
You will receive the validated data in handleSubmit
and send it to the server.
With just a few lines of code, React Hook Form helps us:
- Handle user inputs
- Validate and show appropriate error messages when the form is submitted
- Gives us the validated data when the user inputs the valid data
I removed a lot of things for the sake of brevity.
You can take a look at the full code here
Why is this better?
Better is often subjective, but here are my personal reasons:
- I don’t need to clutter the component with lots of states.
- Lots of built in validations, I only need to describe what they are instead of writing lots of if statements.
- Errors are handled automatically. You can choose whether to show errors when typing or clicking submit button.
- Handles more advanced cases really well, which I will demonstrate in future posts.
- Flexible options. You can choose whether to validate when the form is submitted, or when the fields are modified.
Conclusion
Manual form handling in React is tedious. react-hook-form solves this problem for us, allowing us to write less code.