From 1a024cf9edb1565f7f37736f597c59ee1c5eb8b0 Mon Sep 17 00:00:00 2001 From: Tiago Granelli Ribeiro Date: Wed, 14 Oct 2026 13:12:32 +0200 Subject: [PATCH] docs: recommend useFormState for nested components with React Compiler useForm returns a stable object, so a compiled parent memoizes and useFormContext().formState stays stale. The migration guide now recommends useFormState({ control }) in nested components and destructured methods such as getFieldState. --- src/content/migrate-v7-to-v8.mdx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/content/migrate-v7-to-v8.mdx b/src/content/migrate-v7-to-v8.mdx index 9cec56be1..584eb2537 100644 --- a/src/content/migrate-v7-to-v8.mdx +++ b/src/content/migrate-v7-to-v8.mdx @@ -12,7 +12,24 @@ npm install react-hook-form@beta ## React Compiler {#ReactCompiler} -V8 adds first-class support for the [React Compiler](https://react.dev/learn/react-compiler). No additional configuration is required — React Hook Form is now compatible out of the box. +V8 supports the [React Compiler](https://react.dev/learn/react-compiler). `useForm` returns the same object on every render, so the compiler can't tell when something read through that object changes. Two patterns keep compiled components up to date: + +- In nested components, subscribe with [`useFormState`](/docs/useformstate) instead of reading `formState` from `useFormContext()`. The compiler memoizes `` in the parent, so the context keeps the `formState` from the first render. +- Destructure methods such as `getFieldState` from `useForm()` instead of calling them on the returned object. The compiler memoizes `methods.getFieldState("name")` on `methods`, which never changes. + +```tsx copy +function NestedInput() { + const { register, control } = useFormContext() + const { errors } = useFormState({ control }) // ✅ updates under the compiler + + return ( + <> + +

{errors.name?.message}

+ + ) +} +``` ## Flat Field Array {#FlatFieldArray}