npm / react-hook-form
react-hook-form
What changed in react-hook-form 7, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-17.
react-hook-form 7224 changes
Breaking changes 5
getValues no longer extracts unmarked field array entries.
Changes the location of the minimum-one-item validation error in the errors object.
NaN is no longer treated as empty during validation when valueAsNumber is true.
Field array validation is skipped when mode is onBlur.
Reverts the change that allowed undefined values with async defaultValues in the affected API.
Security 5
Hardens get against prototype-path traversal involving __proto__, constructor, and prototype.
A critical RCE vulnerability was addressed.
A security update addressed CVE-2025-55183.
A security update addressed CVE-2025-55184.
A security update addressed CVE-2025-67779.
New APIs and options 15
Adds an Error Message component for displaying React Hook Form validation errors.
Adds a declaration-merging registry for treating rich third-party types as opaque leaves in recursive type helpers.
trigger() now accepts shouldTouch to mark fields touched after manual or programmatic validation.
Adds a type-safe getErrors method for retrieving form errors.
react-hook-form now supports React Activity.
Exposes resetDefaultValues through form context.
Adds an opt-in delayError option to delay validation error updates.
Adds a FieldArray component for rendering field arrays through control, name, and render props.
Adds a disabled option to useFieldArray; fields expose disabled props when enabled.
Adds resetDefaultValues for updating default form values.
FormProvider context now includes setValues.
Adds setValues for updating form values from a callback or form values object.
useForm now supports built-in asynchronous form-level validation returning success or form errors.
Adds a component that re-renders only when the specified form state changes.
Adds the exact prop to control whether a Controller subscribes to all changes in a user object.
Performance 21
Redundant form-state merges during subscriber notifications are skipped.
Allocations are avoided when matching subscription names.
The watch API is faster.
Improves createFormControl performance for developers using the form control API.
Improves performance for workloads with frequent onChange activity.
Avoids unnecessary value cloning during unregister.
Performance was improved and the bundle size was reduced.
TypeScript performance improves with a hard cap at 10 levels of recursive type depth.
Type performance is improved.
Improves dirty field calculation performance, especially for larger forms and deeply nested values.
Improves re-rendering when useFieldArray is reset.
Reduces bundle size.
setValues threads skipClone through setFieldValue to reduce cloning overhead.
Redundant per-field deep clones are skipped during setValues.
useWatch no longer re-renders when validation occurs on an unrelated field.
setValue skips re-rendering when the value is unchanged.
Submission is memoized to improve performance.
Control context is separated to prevent unnecessary rerenders.
FormProvider context value is memoized to prevent unnecessary rerenders.
isValidating state updates are batched with the validation result.
Batch array updates now skip setValid(), avoiding unnecessary validity recalculation during grouped updates.
Behavior and default changes 8
The Form component's submit behavior was enhanced.
getEventValue now handles file inputs.
Improves the setValue API with value shrinking behavior.
Changes in formState errors now cause child components to re-render with the React compiler.
subscribe can now track submit state through formState.
The Watch API was aligned with useWatch.
useController now reacts when its name changes.
useWatch now reacts when its name changes.
Tooling 2
An optional @types/react peer dependency was added for projects that need React type definitions.
Improved watch type definitions for developers using the watch API.
Fixes and other changes 168
Blur validation works correctly after reset.
Dirty fields checking is improved.
Error updates now produce a new errors reference.
Input values edited before the form is ready are no longer lost.
Form-state tracking is preserved across unsubscribe.
Dirty values extraction now works correctly for fields named hasOwnProperty.
Named scoped subscriptions are improved.
Form value comparison now works correctly for fields named ref.
reset no longer incorrectly sets isDirty when keepDefaultValues is used without values.
setError and clearErrors now produce a new errors reference.
Subject subscription handling is improved.
Subscription value handling is improved.
Fields are no longer incorrectly unregistered while a parent array reindexes.
Removing duplicate indexes now works without mutating the provided indexes.
Fields named after Object.prototype members are no longer marked touched incorrectly on blur or setValue.
Native validation now uses current shouldUseNativeValidation options.
Options removed from props are no longer retained across re-renders.
Watched objects now update after an Activity subtree reconnects.
Array names now prioritize form defaultValues correctly.
watch no longer uses stale shouldUnregister options when registering fields.
Duplicate default value fields are no longer present.
Pending delayError timers for nested paths are now handled correctly.
Nested delayError timers no longer remain when a parent validates clean.
Stale form-level errors are cleared after successful re-validation.
Form-level validation now runs once per traversal.
Form state select option handling was fixed.
getFieldState(name, formState) now updates correctly after reset.
isValid is now recomputed when the errors prop is emptied.
Validation rules removed from register options at runtime are no longer kept active.
Built-in validation results no longer remain stale after reset during handleSubmit.
Form-level validation results no longer remain stale after reset.
Built-in validation results no longer remain stale after reset during onChange.
Resolver results no longer remain stale after reset during onChange.
Nested delayError timers are removed when resetField resets a parent.
setValue now revalidates dependencies when shouldValidate is enabled.
setValue now triggers field array root validation when shouldValidate is enabled.
Required validation now uses the controlled value.
Dirty state is cleared for rows removed from a field array.
Stale field array root errors are cleared after an operation satisfies the validation rule.
Touched field array state is now re-indexed when unsubscribed.
Touched fields handling for field arrays was fixed.
A null array default value no longer incorrectly marks the form dirty.
Form-level validation now uses the current validate function instead of a stale one.
Native validation no longer skips refs without setCustomValidity.
Prevents cleared errors from returning after the delayError timer fires.
Preserves FileList during flatten/expand and omits undefined values in jsonToFormData.
Reads isValidating from the supplied form state.
Preserves resolver-reported root errors during handleSubmit().
Restores publication of the React Server build.
Prevents deleted values from leaking onto surviving field-array items.
Fixes errors and touched state remaining for rows removed by replace().
Keeps dirtyFields synchronized with isDirty when keepValues is enabled.
Prevents stale resolver results from updating form state after reset() during handleSubmit().
Prevents stale resolver state updates after reset().
Clears validating fields when reset() runs.
Fixes stale validating state after resetField().
Calls setCustomValidity once instead of once per key in validate-object mode.
Prevents stale validation types from surviving setError() overwrites.
Preserves nested registered errors when trigger() targets their parent.
Prevents incorrect parent errors when triggering fields with only nested resolver errors.
Recomputes isValidating after unregister() clears validating fields.
Preserves kept values in the submit payload after unregister().
Fixes focus behavior for checkboxes and radio buttons in appended rows.
Prevents stale fields after an Activity subtree reconnects.
Correctly reconciles when an Activity subtree is initially hidden.
Re-subscribes when control changes.
Initializes the compute cache with the initial output.
Fixes Controller under a null parent submitting undefined instead of the field value.
Fixes ERR_MODULE_NOT_FOUND when resolving react-hook-form in Next.js builds.
Fixes resetField not recomputing isValid for subscribe-only consumers.
Fixes inconsistent behavior among useController().field.onChange()-like APIs.
Fixes useFormState failing to reconcile when an Activity subtree is hidden on its first render.
Fixes useWatch ignoring defaultValue when watching an array of names.
Fixes useWatch failing to reconcile when an Activity subtree is hidden on its first render.
Fixes notifications for field array item roots.
Prevents stale errors and touched state after updating a field array item.
Prevents stale field names from leaking into persisted formState.
Fixes custom validity handling when criteriaMode is set to all.
Fixes setting values for fields registered under object or array values.
Corrects keepDirty behavior when unregistering fields.
Fixes stale values when the watched name changes to null.
Fixes validation state checks during form operation.
TypeScript error resolution is fixed for field paths.
setValue no longer emits duplicate values state notifications.
Field array root errors are preserved during array mutations.
Field array paths are no longer recreated by stale renders after field array actions.
useWatch now prefers its own defaultValue over the form's defaultValues.
Min/max validation is no longer skipped for valueAsDate fields.
FormState type definitions were fixed.
The FormState export was fixed.
The component was renamed back from FormStateSubscribe to FormState.
setValue now updates FieldArray values correctly.
Using values with keepDirtyValues no longer silently corrupts arrays or freezes objects during refetch.
Old checkbox and radio elements no longer pollute internal field state.
Argument-less clearErrors() now clears internal errors state correctly.
dirtyFields reference stability is preserved.
useController re-subscribes onChange and onBlur when control changes.
Validation messages can be defined even when their related value is undefined.
Preserves boolean values for dirtyFields on registered array fields.
The FieldArray export was fixed.
Correctly updates dirty state when shouldDirty is used while the form is disabled.
Fixes the name value exposed through form.subscribe after clearErrors.
Makes reset trigger subscribe with the latest name instead of undefined.
Reflects a cleared parent object in controlled fields.
Controller onChange promise handling was fixed.
createFormControl no longer breaks with Fast Refresh in development mode.
Native validation now behaves natively for radio group field validation.
StrictMode no longer removes a field value before the field mounts again.
Controller fields are recovered after reset without requiring a rerender.
Deep equality handling for empty non-plain objects was fixed.
Typing for field arrays with undefined entries was updated.
The isDirty race with an async resolver in onChange mode was fixed.
The reactive values prop takes precedence over defaultValues when shouldUnregister is true.
Fixes FieldArray errors overriding nested fields.
Fixes stale isDirty values in subscribe payloads after reset with keepValues enabled.
Fixes inconsistent reset({}) behavior that previously required a double call.
Preserves values when shouldUnregister is enabled.
Options are passed through setValues so validation can be enabled.
Whole-form changes no longer emit stale name or type values.
append({ obj: null }) is no longer silently replaced by defaultValues after remove().
Reset values are preserved for conditionally mounted Controller fields with shouldUnregister.
defaultValues are preserved when useFieldArray and watch are used together.
Errors state is fixed when using form level validation.
isDirty now stays synchronized with dirtyFields state.
isValidating reactivity is fixed when validatingFields is not subscribed.
Native validation tooltip suppression caused by duplicate submit-error focus is fixed.
Nested setValue updates now notify all matching field-array roots.
Nested resolver field-array errors are preserved in trigger().
TypeScript 4 compatibility is restored for Watch.
remove no longer leaves an array with an empty object when using the values prop.
values updates now propagate to mounted Controller fields.
Empty nodes with false values are pruned from dirtyFields.
isDirty is recomputed after re-registering a previously unregistered field.
Watch updates are preserved when a field array unmounts.
Handles a null parent when unregistering a nested field.
Preserves the previous field value when the useController name changes.
Treats NaN as empty when valueAsNumber is true during field validation.
fieldState errors are improved when resolvers use dot-notation string keys.
Nested fields are handled correctly when the parent defaultValue is null.
register safely accesses field internals during registration.
Dirty state updates correctly after deleting an item when shouldDirty is true.
State updates correctly in watch callbacks when used with Controller, trigger, and reset.
Numeric string keys in defaultValues are now checked correctly for dirty state.
formState.isValid is now correct when a Controller remounts.
Using shouldDirty no longer pollutes unrelated dirty fields.
Checkbox form validation now works correctly with native validation.
useFieldArray no longer marks unrelated fields as dirty.
Targeted field updates now emit the name signal.
The WatchObserver value parameter now uses DeepPartialSkipArrayKey.
Fixed an issue with booleans_as_integers.
isValid now updates when a field's disabled state changes.
Improved invalid date handling in deepEqual and validation.
DeepPartial now handles branded types correctly.
Prevents ghost elements in field arrays when keepDirtyValues is used.
The deprecated names prop is applied first, then overridden when the new name prop is supplied.
Fixed an issue where native validation did not focus the expected field.
Prevents duplicate subscription triggers when setValue is called.
Each subscription now listens only to the changes it subscribes to.
reset now preserves isValid when keepIsValid is used.
A race condition between setError and setFocus was resolved.
The Watch control prop type was corrected.
Validation errors are cleared synchronously during reset(), fixing a Next.js 16 Server Actions issue.
Allows undefined values with async defaultValues in Controller.
Corrects PathValueImpl type inference.
deepEqual now handles NaN comparisons correctly by using Object.is.
isValid is recomputed after reset when form values update asynchronously, keeping reported validity accurate.
watch no longer returns undefined immediately after reset.
Corrected the render function parameter typing for Watch.