React Hook Form

Learn about React Hook Form and how to optimize form creation with it

Forms are documents that provide spaces and or options for people to answer questions. We use forms in our day-to-day life, such as questionnaires, job or visa applications, and so on, in paper or digital format, and they are done mainly for the easier processing of submitted data. We fill out forms online when creating new accounts for services we use, answering questionnaires, or filling out applications for various reasons.

When starting in front-end development we learn how to create forms with just HTML and CSS and make them functional with JavaScript DOM manipulation. However, creating forms this way takes more effort, etc. Working with React libraries makes form handling and validation much more straightforward than with vanilla Javascript. Some React libraries like Formik and Redux form (now upgraded to React Final Form) are used to create forms.

What is React Hook Form?

React Hook Form was created by Bill Luo and maintained by an inclusive team of developers and it is in its 7th version with 29 thousand stars on GitHub and a tiny bundle size of 8.6kb minified + gzipped. It supports Yup, Zod, AJV, Superstruct, Joi, Vest, class-validator, io-ts, nope, and custom build. React Hook Form has certain advantageous features which include but are not limited to providing seamless user experience (UX) and developer experience (DX) because of its feature-complete API when making use of it, it is more performant because it not only removes unnecessary re-renders but also gives you the ability to isolate component re-renders, minimizes code for creating form validation features.

React Hook form is a React library built to handle form validation. As efficient as Formik and React Final Form might be, they do not compare with React Hook Form in terms of cleaner code and the number of dependencies because React Hook Form has zero dependencies and less boilerplate code compared to them.

Implementing React Hook Form Into Form Creation

We will be going through how we can apply the React Hook Form library in creating a form. In this article, we will make a simple form containing standard features like name, email address, date, and password.

Installing React Hook Form

We make sure we have Node.js in our system by running the following command

node -v

Running this command should either print out the node’s version number, mine is

v17.7.1

or display an error message that indicates that we don’t have Node.js installed in our system.

An error message like this

‘node’ is not recognised as an internal or external command, operable program or batch file.

Then we start by creating a new React application by running the following command

npx create-react-app react-hook-form-demo

Upon completion of the app creation, move to the newly created project’s root directly by running this command

cd react-hook-form-demo

Then we start our form creation process by installing React Hook Form by running the following command:

npm install react-hook-form-demo

or

yarn add react-hook-form-demo

Thereafter, we import useForm from the React Hook Form library into our React app by copying this into our code editor

import {useForm} from “react-hook-form”;

useForm is a hook that is used to manage forms. It returns an object that contains properties that enable form management. These methods include register, handleSubmit, unregister, errors, watch, reset, setError, clearError, setValue, getValue, triggerValidation, control, and formState.

Below is a simple React Hook Form template that will give us a basic understanding of React Hook Form usage.

import React from “react”;
import {useForm} from “react-hook-form”;

let UserLogin = () => {
    const {register, handleSubmit} = useForm();
    const submitFormt = () => (data) => console.log(data);

return (
    <div>
        <form>
            <div>
                <label>Username</label>
                    <input type=”text” name= ”username” {... register    (“username”)} />
            </div>

            <div>
                <label>Password</label>
                <input type=”password” name= ”password” {... register (“password”)} />
            </div>
</form>
</div>

)

export default UserLogin ;

Registering components with React Hook Form

When creating forms with React Hook Form we have to register our components into the useForm() hook to make the values in our form available for validation and submission.

useForm() hook returns an object that contains different methods; register, unregister, formState, watch, handleSubmit, reset, resetField, setError, clearError, setValue, setFocus, getValues, getFieldState, trigger, control. The React Hook Form documentation on useForm gives a very detailed explanation of each of the methods.

Replace the code in our editor with the one below.

import React from “react”;
import {useForm} from “react-hook-form”;

let UserLogin = () => {
    const {register, handleSubmit} = useForm();
    const onSubmit = data => console.log(data);

    return (

    <form onSubmit= {handleSubmit(onSubmit)} />
        <input {...register(“firstName”)}/>
        <input {...register(“lastName”)}/>
        <input {...register(“email”)}/>
        <input {...register(“password”)}/>
        <button>Submit</button>
</form>

export default UserLogin();

Validating form components with React Hook Form

Good web forms help you to fill your forms in the right manner before they can be submitted.

Have you ever tried filling out a web form and noticed that your form couldn’t submit? On scrolling backwards to figure out what could have been the problem, you see that there are some messages on some of the form fields that say things such as Incorrect password, Incorrect username, This field's required Password should be between 10 to 20 characters long.

These error messages that reflect the constraints to submitting the form are features of form validation. Form validation is a security feature which ensures that everything on both the server side and the client side is in the correct format before the submission of the form can go through. React Hook Form provides the error messages as an object type (error). We will talk about this in the next subsection.

React hook form technique for form validation is in alignment with the HTML standard for form validation.

Some form validation rules include but are not limited to ref required, maxLength, minLength, max min pattern, valueAsNumber, valueAsDate, disabled.

required

This rule makes form submission possible only on the condition that the fields that have been marked as “ required “ have been filled out.

maxLength

This rule can only permit form submission when the string values filled into a particular field do not exceed the set number of values the field should contain.

minLength

The minLength ensures that the user does not exceed the specified number of string values.

min

This rule permits form submission only when the numerical values that are filled into a particular form field aren’t fewer than the stipulated number of values for that field.

max

This rule ensures that the user does not exceed the specified number of numerical values for that form field.

pattern

This rule ensures that the user follows the specified pattern for filing out the particular form field else it throws an error. An example could be seen when filling out a field that was set to receive values in capital letters.

disabled

Enabling this rule by setting it to “true” means that a user cannot input value into that form field. Sometimes, form creators use this feature to demonstrate to users how to fill out a form.

Replace the previous code in our editor with the one below.

import React from “react”;
import {useForm} from “react-hook-form”;

let UserLogin = () => {
const {register, handleSubmit} = useForm();
const onSubmit = (data) => console.log(data);

return(
    <form>
        <input {...register(“firstName”, { required: true, minLength: 8, maxLength: 15 } ) } />
        <input {...register(“lastName”, {required: true, minLength: 8, maxLength: 10 } ) } />
        <input {...register(“email”, {required: true, maxLength: 20 } ) } />
        <input type=”password” name=”password”{...register(“password”, {required:true, min: 10, max: 20 } ) } />
        <button>Submit</button>
</form>
)

export default UserLogin();

Error handling

Form validation and error handling go hand in hand. When form fields are not filled in the specified format or are not filled out at all, the React Hook Form error object enables the user to see errors in the form and make necessary changes to the specified form fields. The error object returns error messages that inform the user of the constraints to a successful form submission.

import React from “react”;
import {useForm} from “react-hook-form”;

let UserLogin = () => {
const {register, handleSubmit} = useForm();
const onSubmit = (data) => console.log(data);

return(
    <form>
        <input {...register(“firstName”, { required: true, minLength: 8, maxLength: 15 } ) } />
        {errors.firstName? .type=== ‘required’ && “ *required ”}

        <input {...register(“lastName”, {required: true, minLength: 8, maxLength: 10 } ) } />
{errors.lastName? .type=== ‘required’ && “ *required ”}

        <input {...register(“email”, {required: true, maxLength: 20 } ) } />
{errors.email? .type=== ‘required’ && “ *required ”}
        <input type=”password” name=”password”{...register(“password”, {required:true, min: 10, max: 20 } ) } />
{errors.password? .type=== ‘required’ && “ *required ”}

        <button>Submit</button>
</form>
)

export default UserLogin();

Integration with UI libraries

React Hook Form enables easy integration with external UI libraries. React Hook Form handles external UI component library integration with forms and in cases where the component doesn’t support `ref, it employs the Controller component. It is employed like this

const {control, handleSubmit} = useForm();

To understand this React Hook Form’s integration with UI libraries, refer to this article.

React Hook Form in React Native

React Hook Form is used to efficiently create forms in React Native. It also employs the Controller component.

import React from "react";
import { Text, View, TextInput, Button, Alert } from "react-native";
import { useForm, Controller } from "react-hook-form";

export default function App() {
  const { control, handleSubmit, formState: { errors } } = useForm({
    defaultValues: {
      firstName: '',
      lastName: '',
      email: ",
      password: "
    }
  });
  const onSubmit = data => console.log(data);

  return (
    <View>
      <Controller
        control={control}
        rules={{
         required: true,
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <TextInput
            style={styles.input}
            onBlur={onBlur}
            onChangeText={onChange}
            value={value}
          />
        )}
        name="firstName"
      />
      {errors.firstName && <Text>This is required.</Text>}

      <Controller
        control={control}
        rules={{
         maxLength: 100,
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <TextInput
            style={styles.input}
            onBlur={onBlur}
            onChangeText={onChange}
            value={value}
          />
        )}
        name="lastName"
      />

      <Controller
        control={control}
        rules={{
         required: true,
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <TextInput
            style={styles.input}
            onBlur={onBlur}
            onChangeText={onChange}
            value={value}
          />
        )}
        name="email"
      />
      {errors.email && <Text>This is required.</Text>}


      <Controller
        control={control}
        rules={{
         required: true,
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <TextInput
            style={styles.input}
            onBlur={onBlur}
            onChangeText={onChange}
            value={value}
          />
        )}
        name="password"
      />
      {errors.password && <Text>This is required.</Text>}

      <Button title="Submit" onPress={handleSubmit(onSubmit)} />
    </View>
  );
}

TypeScript

Guess what language React Hook Form was built with? TypeScript! Many lovers of TypeScript will find this exciting because of TypeScript’s strictly-typed feature. TypeScript coders also believe that the forms will be more secure and bug-free when created with TypeScript. To learn more about how to implement TypeScript in React Hook Form check out this awesome article.

Conclusion

React Hook Form enables building forms efficiently without using a large boilerplate code.