Capítulo 4 de 39

Chapter 4: Migrate V7 to V8 (Beta)

Core Idea

V8 is a beta release focused on React Compiler compatibility and a handful of targeted breaking changes; most V7 code keeps working, but field.ref semantics in Controller/useController and a few useFieldArray details change.

Key Concepts

  • React Compiler support: V8 works with React Compiler out of the box, no extra configuration.
  • Flat field arrays (types-only): useFieldArray types now accept primitive arrays (string[]) instead of forcing { value: string }[] — but as of the current beta this is types-only; fields still spreads each entry with { ...field, key } internally, so primitive-array rendering needs verification before relying on it in production.
  • field.ref becomes the real DOM node: in V7, Controller/useController's field.ref was a partial proxy exposing only focus/select/setCustomValidity/reportValidity. In V8 it's the actual DOM element, so any native method/property is available.
  • useFieldArray id → key: the internal render identifier is renamed from id to key; you can still store your own id/key as field data without it affecting the render key.
  • Watch component prop rename: <Watch names={...} /> becomes <Watch name={...} />.
  • watch callback → subscribe: the WatchObserver type for watch's callback overload is removed from the public API; subscribe is the fully-typed replacement going forward (the callback form of watch still runs at runtime in the current beta, you just lose the named type).

Reference Tables

V7V8Notes
field.ref.focus (proxy, fixed method set)field.ref (real DOM node)any native property/method now available
fields[0].idfields[0].keyrender identifier renamed
keyName option on useFieldArrayremovedrender key is always key
<Watch names={[...]} /><Watch name={[...]} />prop renamed for API consistency
watch((value, {name,type}) => ...)subscribe({ formState: { values: true }, callback })fully typed replacement

Anti-patterns

  • Relying on flat useFieldArray primitive arrays rendering correctly in the current beta: it's a types-only change so far; verify actual rendering behavior before shipping.
  • Assuming setValue no longer touches useFieldArray entries: that change is planned but not shipped yet in the current beta — setValue still updates field-array fields directly; use replace from useFieldArray to overwrite an entire array.

Key Takeaways

  1. Most V7 code runs unchanged on V8 — the breaking changes are narrow and mostly affect Controller/useController/useFieldArray power users.
  2. field.ref in Controller/useController now exposes the full DOM node instead of a restricted proxy.
  3. subscribe is the forward-looking replacement for watch's callback-with-options form.

Connects To

  • useFieldArray: the hook whose id/keyName/flat-array behavior changed.
  • usecontroller / usecontroller-controller: where field.ref semantics changed.
  • useform-subscribe: the typed replacement for watch's callback overload.
  • useform-setvalue: replace (from useFieldArray) is the recommended way to overwrite a whole array today.