Capítulo 10 de 39
formState (from useForm() directly) tracks the whole form's interaction/validation status — dirty/touched fields, submission state, validity, and errors — wrapped in a Proxy that only subscribes to the specific properties you actually read.
const { isDirty } = formState); reading a property later (in a callback) or conditionally skips the subscription, so the component won't re-render on that change.isDirty is whole-form (requires defaultValues to compare against); dirtyFields is per-field and can diverge from isDirty (e.g. field-array insert/remove changes isDirty without marking any individual field dirty).resolver, or with mode beyond default onSubmit, or after an explicit trigger()/submit; setError immediately forces it false, but that's not derived from real validation and gets overwritten on the next validation run.setValue in its own effect before this is ready can misbehave — gate such early writes on isReady.defaultValues.const {
setValue,
formState: { isReady },
} = useForm()
// Parent: safe
useEffect(() => setValue("test", "data"), [])
// Child component: gate on isReady
useEffect(() => isReady && setValue("test", "data"), [isReady])
isReady matters specifically for child components writing to the form before the subscription is guaranteed set up.| Field | Meaning |
|---|---|
isDirty / dirtyFields | whole-form vs per-field modification tracking |
touchedFields | per-field interaction tracking |
defaultValues | the values useForm/reset last set |
isSubmitted / isSubmitSuccessful / submitCount | submission history |
isSubmitting | true while a submit is in flight |
isLoading | true while async defaultValues load |
isValid / isValidating / validatingFields | validity and in-flight validation tracking |
errors | field error object |
disabled | mirrors useForm's disabled option |
isReady | true once the subscription is fully initialized |
const formState = useForm().formState kept around and read from later: defeats the Proxy — destructure at the point of use.setValue from a child's mount effect without checking isReady: can race the form's own subscription setup.formState keys you need, at render time.isValid needs a validation pass to be trustworthy — it isn't live-derived from nothing.isReady exists specifically to avoid races when a child writes to the form very early.isValid false without a real validation pass.