Skip to content

watch

Subscribe to input changes

watch: (names?: string | string[] | (data, options) => void) => unknown

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.

Props

TypeDescription
stringWatch input value by name (similar to lodash get function)
string[]Watch multiple inputs
undefinedWatch all inputs
(data: unknown, { name: string, type: string }) => voidWatch all inputs and invoke a callback

Return

ExampleReturn
watch('inputName')unkown
watch(['inputName1'])unknown[]
watch(){[key:string]: unknown}
watch((data, { name, type }) => console.log(data, name, type)){ unsubscribe: () => void }

Rules

  • When defaultValue is not defined, the first render of watch will return undefined because it is called before register. It's recommend to provide defaultValues at useForm to avoid this behaviour, but you can set the inline defaultValue as the second argument.

  • When both defaultValue and defaultValues are supplied, defaultValue will be returned.

  • This API will trigger re-render at the root of your app or form, consider using a callback or the useWatch api if you are experiencing performance issues.

  • watch result is optimised for render phase instead of useEffect's deps, to detect value update you may want to use an external custom hook for value comparison.

Examples

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

function App() {
  const { register, watch, formState: { errors }, handleSubmit } = useForm();
  const watchShowAge = watch("showAge", false); // you can supply default value as second argument
  const watchAllFields = watch(); // when pass nothing as argument, you are watching everything
  const watchFields = watch(["showAge", "number"]); // you can also target specific fields by their names

  // Callback version of watch.  It's your responsibility to unsubscribe when done.
  React.useEffect(() => {
    const subscription = watch((value, { name, type }) => console.log(value, name, type));
    return () => subscription.unsubscribe();
  }, [watch]);

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

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input type="checkbox" {...register("showAge")} />
        
        {/* based on yes selection to display Age Input*/}
        {watchShowAge && <input type="number" {...register("age", { min: 50 })} />}
        
        <input type="submit" />
      </form>
    </>
  );
}
import React from "react";
import { useForm } from "react-hook-form";

interface IFormInputs {
  name: string
  showAge: boolean
  age: number
}

function App() {
  const { register, watch, formState: { errors }, handleSubmit } = useForm<IFormInputs>();
  const watchShowAge = watch("showAge", false); // you can supply default value as second argument
  const watchAllFields = watch(); // when pass nothing as argument, you are watching everything
  const watchFields = watch(["showAge", "age"]); // you can also target specific fields by their names

  // Callback version of watch.  It's your responsibility to unsubscribe when done.
  React.useEffect(() => {
    const subscription = watch((value, { name, type }) => console.log(value, name, type));
    return () => subscription.unsubscribe();
  }, [watch]);

  const onSubmit = (data: IFormInputs) => console.log(data);

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input {...register("name", { required: true, maxLength: 50 })} />
        <input type="checkbox" {...register("showAge")} />
        {/* based on yes selection to display Age Input*/}
        {watchShowAge && (
          <input type="number" {...register("age", { min: 50 })} />
        )}
        <input type="submit" />
      </form>
    </>
  );
}
import * as React from "react";
import { useForm, useFieldArray, ArrayField } from "react-hook-form";

function App() {
  const { register, control, handleSubmit, watch } = useForm();
  const { fields, remove, append } = useFieldArray({
    name: "test",
    control
  });
  const onSubmit = (data: FormValues) => console.log(data);
  
  console.log(watch("test")); 

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {fields.map((field, index) => {
        return (
          <input
            key={field.id}
            defaultValue={field.firstName}
            {...register(`test[${index}].firstName`)}
          />
        );
      })}
      <button
        type="button"
        onClick={() =>
          append({
            firstName: "bill" + renderCount,
            lastName: "luo" + renderCount
          })
        }
      >
        Append
      </button>
    </form>
  );
}

Video

The following video tutorial demonstrates watch API.

Thank you for your support

If you find React Hook Form to be useful in your project, please consider to star and support it.

Edit