How to Use React Hook Form with TypeScript
Tags: typescript, react, javascript, programming
Published: 2023-08-01 05:35:59

**To read more articles like this, [visit my blog](https://www.mohammadfaisal.dev/blog)**



Handling form inputs are an absolute necessity for any modern web application. React is no exception. We can handle form in multiple ways. But ensuring re-usability and performance is especially critical for forms.

Because forms are some of the most dynamic components and if you handle it incorrectly your users will feel the pain of using a sluggish application.

Today we will look into an awesome library named [react-hook-form](https://react-hook-form.com/) which enables us to create clean and performant form components.

## But what about other solutions?

Good question. There are other libraries like `Formik` and `Redux Form` doing almost the same thing in a different approach. But, React hook form is better in several ways.

* Less Boilerplate

* Less Rendering compared to others

* Better support for Schema Validation.

## What are we going to build?

Today we will build a simple authentication form where a user will be able to

* Give `Email` and `Password` as input

* Will have `validation` for filtering data.

We will start simple and see how we can progress step by step.

### Step 1. Install Dependencies

Let’s first install dependencies

```js
yarn add react-hook-form
```

### Step 2. Import Hook

Import the the `useForm` hook from the library. This hook exports all the necessary controls for our form.

```js
import { useForm } from "react-hook-form";
```

### Step 3. Define Interface for our data

As we are using TypeScript we should take advantage of the type system. The best part is it catches the error at compile time if you have any typos.

```js
type Inputs = {
  email: string
  password: string
}
```

### Step 4. Build the Form

Following is the complete code for our form. Here we are extracting two controls from the hook.

`register` -> This is necessary for binding our form inputs to the library.

`handleSubmit` -> This is the standard submit function.

```js
import React from 'react'
import { useForm } from 'react-hook-form'

type Inputs = {
    email: string
    password: string
}

export default function FormSignUp() {
    const { register, handleSubmit } = useForm<Inputs>()

    const onSubmit = (data) => console.log(data)

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <input {...register('email')} />
            <input {...register('password')} />
            <input type='submit' />
        </form>
    )
}
```

Here one thing to note is we get the value as an object inside the onSubmit function. Like the following:

![after the submit is clicked](https://cdn-images-1.medium.com/max/3368/1*7pZ4-iDyQuUuROV0iola2A.png)

### Step 5. Add a default value

Sometimes we want to add a default value in our form fields. In those scenarios, you can add the `defaultValue` property like the following

```js
<input *defaultValue*='default@email.com' {...register('email')} />
```

And now your form will look like this:

![Default email](https://cdn-images-1.medium.com/max/2000/1*egNXcxX4TP6_iXoQW8hybQ.png)

### Step 6. Validation

A famous philosopher once said: *“What are forms without validation?”*

So now we will see how we can add validation in our form. There are several validations available for us out of the box

* `required` (make a field mandatory)

* `min` (for numbers)

* `max` (for numbers)

* `minLength` (for the length of the field)

* `maxLength` (for the length of the field)

* `pattern` (for pattern matching like valid password/email)

You can read more about them [here](https://react-hook-form.com/api/useform/register)

Now we will make sure that our users just give input of their email and the password must be 6 characters long.

```js
<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register('email', { required: true })} />
  <input {...register('password', { minLength: 6 })} />
</form>
```

Okay, we have made the field mandatory but **how do we catch the error**? For that, we need to import `errors` from inside the hook

```js
const {register,handleSubmit,*formState*: {errors}} =useForm<*Inputs*()
```

Finally, our form looks something like this

```js
import React from 'react'
import { useForm } from 'react-hook-form'

type Inputs = {
    email: string
    password: string
}

export default function FormSignUp() {
    const {register,handleSubmit,formState: { errors }} = useForm<Inputs>()

    const onSubmit = (data) => console.log(data)

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <input {...register('email', { required: true })} />
            {errors.email && <span>This field is required</span>}
            <input {...register('password', { minLength: 6 })} />
            {errors.password && <span>This field must be 6 characters long</span>}
            <input type='submit' />
        </form>
    )
}
```

Now when you try to submit without the email filled up the errors will come up.

![validation](https://cdn-images-1.medium.com/max/2000/1*1LIVxMpf20qZVwY7MswH1Q.png)

### Step 7: Let’s clean up even more

I personally don’t like passing validation logic into the input itself. Also, the default control that we get is not that extensive.

In this scenarios we can use some kind of **schema validation** library like `Yup` which is really popular.

To use that what we first need to install the dependency

```js
yarn add @hookform/resolvers yup
```

Then build the schema validator.

```js
import { yupResolver } from '@hookform/resolvers/yup'
import * as yup from 'yup'


const schema = yup.object().shape({
    email: yup.string().required(),
    password: yup.string().min(6)
})
```

and pass the schema into the `useForm` hook

```js

const {register, handleSubmit,formState: { errors }} = useForm<Inputs>({
    resolver: yupResolver(schema)
})
```

Now our form will be a lot cleaner than before:

```js
<form onSubmit={handleSubmit(onSubmit)}>
    <input {...register('email')} />
    {errors.email?.message}
    <input {...register('password')} />
    {errors.password?.message}
    <input type='submit' />
</form>
```

So now both our form and error handling becomes cleaner. and does the same job as before.

![validation](https://cdn-images-1.medium.com/max/2000/1*asMlrRYUM0i2L1Ud7p_fnA.png)

### Conclusion

There you have it. We’ve seen how we can use the `react-hook-form` library to write clean and performant form components without the hassle of boilerplate. Have a great day!

**Have something to say? Get in touch with me via [LinkedIn](https://www.linkedin.com/in/56faisal/) or [Personal Website](https://www.mohammadfaisal.dev/)**