--- title: Read Every formState Property You Depend On During Render impact: MEDIUM impactDescription: prevents a component that never re-renders when the state it shows changes tags: formstate, formState, proxy, subscription, conditional --- ## Read Every formState Property You Depend On During Render `formState` is a Proxy: each property has a getter that marks it subscribed the first time it is read. Subscription is established by the *read*, not by how you write it — `formState.isValid`, `const { isValid } = formState`, and destructuring in the `useForm` call are all equivalent, and all three subscribe to exactly `isValid`. (The common claim that touching the whole object "disables the optimization" is not true; the getters are per-property.) The real trap is a property that is never read during render. Read it only inside a callback, or only in a branch that doesn't run on the first render, and the getter never fires — so RHF never re-renders the component when that property changes, and the UI silently stops updating. **Incorrect (isSubmitting is only read inside the handler — the button label never updates):** ```typescript function SaveButton() { const { handleSubmit, formState } = useForm({ defaultValues: emptyDraft }) const onClick = handleSubmit(async (values) => { if (formState.isSubmitting) return // First read happens in a callback, after render await saveDraft(values) }) return } ``` **Correct (read it in the render body, so the subscription exists):** ```typescript function SaveButton() { const { handleSubmit, formState: { isSubmitting } } = useForm({ defaultValues: emptyDraft }) const onClick = handleSubmit(async (values) => { await saveDraft(values) }) return ( ) } ``` The same applies to a conditional read: `{step === 2 && errors.email && …}` does not subscribe to `errors` until `step` reaches 2. Destructuring at the top of the component is the habit that makes this a non-issue, which is the real reason to do it. Reference: [formState](https://react-hook-form.com/docs/useform/formstate) · [useFormState](https://react-hook-form.com/docs/useformstate)