Back to Top

How to Implement useForm() Hook in Nextjs | React

Updated 14 February 2023

Hello,

In this post, we will learn the use of useForm Hook in React JS.

What is useForm Hook?

useForm() is a custom hook. It is a hook for form validation. The purpose of useForm Hook is to manage forms with ease. It takes one object as an optional argument. 

The useForm has the following properties-

NameTypeDescription
onSubmitstringValidation will trigger on the submit event and inputs will attach onChange event listeners to re-validate them.
onBlurstringValidation will trigger on the blur event.
onChangestringValidation will trigger on the change event with each input, and lead to multiple re-renders. Warning: this often comes with a significant impact on performance.
onTouchedstringValidation will trigger on the first blur event. After that, it will trigger on every change event.Note: when using with Controller, make sure to wire up onBlur with the render prop.
allstringValidation will trigger on the blur and change events.

Return :

The following list contains references to useForm return props.

Installation

Installing React Hook Form only takes a single command and you’re ready to roll.

npm install react-hook-form

Syntax :

const {register,handleSubmit,watch,formState:{errors}} = useForm();

register: This method allows you to register an input or select an element and apply validation rules to React Hook Form. Validation rules are all based on the HTML standard and also allow for custom validation methods.

formState: This object contains information about the entire form state. It helps you to keep on track with the user’s interaction with your form application. There are many return props for the formState. In addition, we use errors: An object with field errors, defaultValues: the value which has been set at useForm’s defaultValues or updated defaultValues via reset  API.

Start your headless eCommerce
now.
Find out More

watch: This method will watch specified inputs and return their values. It is useful to render input value and for determining what to render by condition.

handleSubmit: This function will receive the form data if form validation is successful.

Let’s take a small example to understand useForm –

To create Magento’s Customer Address Page in Nextjs (React) using useForm hook.

  • This is part one of the Blog, in which we are focussing on the form part of the page and storing the data of the form in the formData object using the watch.
  • We are able to show and hide the values coming in after save using the useState.
  • We have a LoginForm Component to make a form that uses the useForm Hook and then we return a form.
  • We add the onSubmit event & pass the handleSubmit which consoles the form data on click to Save button.
  • In the Input, we invoke the register and also use options to validate accordingly.
import React, { useState } from "react";
import { useForm } from "react-hook-form";

const LoginForm = () => {
  const {
    register,
    watch,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const [show, setShow] = useState(false);
  const formData = watch();

  const formSubmit = (data) => {
    console.log(data);
    setShow(true);

  };

  return (
    <form onSubmit={handleSubmit(formSubmit)}>
      <div className="form-container">
        <label className="label">Account Information</label>
        <input
          {...register("firstName", { required: true })}
          placeholder="First name"
        />

        {errors.firstName && <p className="error">First Name is required.</p>}

        <input
          {...register("lastName", { required: true, minLength: 2 })}
          placeholder="Last name"
        />

        {errors.lastName && <p className="error">Last Name is required.</p>}
        <input
          {...register("company", { required: true })}
          placeholder="Company"
        />

        <input
          type="email"
          {...register("email", { required: true })}
          placeholder="Email"
        />
        {errors.email && <p className="error">Email address is required.</p>}

        <input
          type="tel"
          {...register("phone", { required: true,valueAsNumber:true })}
          placeholder="Phone Number"
        />
        {errors.phone && <p className="error">Phone Number is required.</p>}

        <label className="label">Address</label>

        <input
          {...register("address", { required: true })}
          placeholder="Street Address"
        />
        {errors.address && <p className="error">Street Address is required.</p>}

        <input {...register("addressL2")} placeholder="Street Address 2" />
        <input {...register("addressL3")} placeholder="Street Address 3" />

        <input {...register("city", { required: true })} placeholder="City" />
        {errors.city && <p className="error">City name is required.</p>}

        <input
          {...register("zip", { required: true, valueAsNumber: true })}
          placeholder="Zip"
        />
        {errors.zip && <p className="error">Zip Code is required.</p>}

        <input
          type="text"
          {...register("country", { required: true })}
          placeholder="Country"
        />
        {errors.country && <p className="error">Country name is required.</p>}

        <input
          {...register("state", { required: true })}
          placeholder="State/Province"
        />
        {errors.country && <p className="error">State/Province is required.</p>}
      </div>

      <div className="formData">
        <input className="btn" type="submit" value="Save" />
        {show ? (
          <div className="formValues">
            <p className="values">{formData.firstName}</p>
            <p className="values">{formData.lastName}</p>
            <p className="values">{formData.company}</p>
            <p className="values">{formData.email}</p>
            <p className="values">{formData.phone}</p>
            <p className="values">
              {formData.address}, {formData.addressL2}, {formData.addressL3}{" "}
            </p>
            <p className="values">{formData.city}</p>
            <p className="values">{formData.zip}</p>
            <p className="values">{formData.country}</p>
            <p className="values">{formData.state}</p>
          </div>
        ) : ""}
      </div>
    </form>
  );
};

export default LoginForm;

We have imported the LoginForm Component in the index page and rendered the form in the main section. We have styled our CSS in the required way, you can customize it as per your needs.

In this Code, the register(“string”) registers the input, required: true makes it mandatory to fill in the input, the form data won’t be submitted until we fill in the input field. To throw the errors we initially used the formState: {errors} object. An object with field errors. There is also an  ErrorMessage component to retrieve error messages easily. Via this “errors” object we are able to show the errors as per various inputs.
As mentioned above, in case we need to pass the error message instead of using the formState: errors. We can directly go for Register with validation and error message instead of Register with validation we used in the input. Example –

{/*<strong>Register with validation</strong>*/}

<input
  {...register("test", {
    required: true
  })}
/>

{/*Register with validation and error message*/}

<input
  {...register("test", {
    required: 'error message' // JS only: <p>error message</p> TS only support string
  })}
/>

Let’s see the output below.

Image on submitting Empty Form using required validation
On submitting the Empty form.
Form data getting displayed when form validations gets successful using the handleSubmit.
Form Data gets stored in formData & rendered on form validations getting successful.

This is a small example to understand the useForm Hook in React. To Clear any doubt you can read again.

In the second part, we will be using useQuery hook to save the data from the form. useQuery is a custom hook within React Query used to fetch data in a React application. Under the hood, these hooks manage lots of things such as caching data after the initial fetch, re-fetching data in the background, etc.

Moving ahead will store and manage the data using Apollo Client. Apollo Client is a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. Finally will see the use of Magento API to create the integration process easier with custom data and for less complexity.

Stay tuned till then.


Happy Coding !!

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home