Capítulo 26 de 39

Chapter 26: watch

Core Idea

watch subscribes to and returns input value(s), triggering a re-render at the root of useForm when they change — the un-isolated counterpart of useWatch.

Key Concepts

  • Four overloads: watch(name, defaultValue?) → single value; watch(names[], defaultValues?) → array of values; watch() → entire form values; watch(callback, defaultValues?) → subscribe without re-rendering (deprecated, migrate to subscribe).
  • defaultValue precedence: if both useForm's defaultValues and watch's inline defaultValue are supplied, defaultValues wins; the inline one is only a fallback for a field with no value at all. Without either, the first render's watch call returns undefined because it runs before register.
  • Root-level re-render: watch re-renders wherever useForm/watch was called — for large forms, prefer useWatch (or subscribe for the no-render callback case) to scope the re-render.
  • Render-phase optimized, not effect-phase: like useWatch, its result isn't meant for useEffect dependency comparisons; use a dedicated value-comparison hook for that.
  • Callback overload's type argument: 'change' for a real user-driven DOM event, undefined when the change was programmatic (setValue, reset, after unregister).

Code Examples

const watchShowAge = watch("showAge", false)   // single field, with fallback default
const watchAllFields = watch()                  // entire form
const watchFields = watch(["showAge", "age"])   // several fields

{watchShowAge && <input type="number" {...register("age", { min: 50 })} />}
  • What it demonstrates: conditionally rendering a field based on another field's live value — watch's most common use.
const { fields, remove, append } = useFieldArray({ name: "test", control })
console.log(watch("test")) // watch the whole array's current values
  • What it demonstrates: watch reading a field array's live values, paired with useFieldArray for the row structure itself.

Anti-patterns

  • Using root-level watch in a large form where only a small subtree needs the value: causes the entire form-holding component to re-render; use useWatch instead.
  • Using the deprecated callback overload in new code: migrate to subscribe, which is the maintained no-render subscription API.
  • Using watch's return value as a useEffect dependency expecting change-detection semantics: it's render-phase optimized, not built for that.

Key Takeaways

  1. watch is convenient at the root but re-renders broadly — reach for useWatch in bigger forms.
  2. The callback form is deprecated; use subscribe for the no-render case going forward.
  3. defaultValues (on useForm) beats an inline watch default whenever both are present.

Connects To

  • usewatch: the isolated-re-render alternative.
  • useform-subscribe: the maintained no-render subscription API, replacing the deprecated callback overload.
  • usefieldarray: a common pairing for computing derived totals from array values.