Guide to react form hook and watch vs useWatch

Junaid JavedJunaid Javed
3 min read

I have never used react-form-hook before my current project. I was creating a boilerplate and he suggested I use react-form-hook in this project. So I am using it now. There is a bundle of options other than react-form-hook still it is much cleaner and helps to avoid re-rendering. It is my must-use library for my next projects. From now on I will use it for react-form-hook or rfh. I am lazy and don't want to write complete spellings.

Installation

npm install react-hook-form

There are multiple ways to use rfh like using the register method or using provider. Although I will be using Controller

react-form-hook-site

Implementation

We have created a form with two fields. It will behave like an uncontrolled form and will not do any extra rendering. What if we want to make it reactive and change the value of a component concerning the value we entered in the form?

import React from "react";
import { useForm } from "react-hook-form";
import useRenders from "./useRenderHook";

const BasicForm = () => {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm();
  const renderCount = useRenders()
  const onSubmit = (data) => console.log(data);

  const value = watch("example");

  return (
    <>
    <p>Render Count : {renderCount}</p>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input defaultValue="test" {...register("example")} />
        <br />
        <input {...register("exampleRequired", { required: true })} />
        {errors.exampleRequired && <span>This field is required</span>}
        <br />
        <input type="submit" />
      </form>
      <h1>{value}</h1>
    </>
  );
};

export default BasicForm;

There are ways to get values from the form.

  1. getvalue('name')

  2. watch()

  3. useWatch()

We can use getValue when we want to get value on a specific action like a button click. Now we will talk about watch and useWatch() As the name says, watch continuously watch the values and return the value.

In the above code snippet, we used the watch method to get value. Watch method watches the values and returns all values or expected values on every key stoke in form. It works at the root level. It means that if you want to watch any value you need to use it at the root of your component.

In the above code snippet, I used to watch at the root of my form and it cause a loot re-rendering.

I created another component `Inputvalue`.

import React from "react";
import { useForm } from "react-hook-form";

const Inputvalue = () => {
  const { watch } = useForm();

  const value = watch("example");
  return <h1>Value:{value}</h1>;
};
export default Inputvalue;

It is not giving value because it doesn't know whose value I need to watch and return.

We have a hook useWatch hook. It takes control and the name of the input field. Control is a object that comes by default with rfh and it has a method for registering component or input fields.

I updated my Basic Form and Inputvalues

// BasicForm
import React from "react";
import { useForm } from "react-hook-form";
import useRenders from "./useRenderHook";
import Inputvalue from "./InputValue";

const BasicForm = () => {
  const {
    register,
    handleSubmit,
    control,
    formState: { errors },
  } = useForm();
  const renderCount = useRenders();
  const onSubmit = (data) => console.log(data);

  return (
    <>
      <p>Render Count : {renderCount}</p>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input defaultValue="test" {...register("example")} />
        <br />
        <input {...register("exampleRequired", { required: true })} />
        {errors.exampleRequired && <span>This field is required</span>}
        <br />
        <input type="submit" />
      </form>
      <Inputvalue control={control} />
    </>
  );
};

export default BasicForm;
// Input Value
import React from "react";
import { useWatch } from "react-hook-form";
import useRenders from "./useRenderHook";

const Inputvalue = ({control}) => {
  const value = useWatch({control, name:'example'});
  const renderCount = useRenders()

  return <>
  <p>Render Count: {renderCount} </p>
  <h1>Value:{value}</h1>;
  </>
};
export default Inputvalue;

Now Only InputValue is re-rendering. Even the Input form is Not re-rendering. This is the benefit of react-form-hook.

That is all.

Here is the end from my side.

0
Subscribe to my newsletter

Read articles from Junaid Javed directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Junaid Javed
Junaid Javed

I was rusting so i decided to learn Rust.