Repository navigation
[v2] [RFC] What should happen when Field and FormGroup unmount? #2296
Description
Activity
- pinned this issue
on Aug 9, 2026 - addedv2This issue affects v2 as well.This issue affects v2 as well.scope: coreThis issue affects the core package, meaning any adapter is also affected by it.This issue affects the core package, meaning any adapter is also affected by it.area: runtimeThis issue affects the runtime of the library.This issue affects the runtime of the library.
on Aug 9, 2026 We use Tanstack Form for a very complex multi step form. This contains steps and also substeps. the new Form Group Api makes handling the each part individually very handy.
We only render the current active subStep. For the open questions I would handle them:- I would expect that the listener remains active, it's part of the logic.
- I would expect that the validator still runs, For us it's very important that all validation logic runs
- I would say yes, but no hard opinion on that.
The v2 alpha looks amazing. Nice work !
Reacted by LeCarbonator and Jaime R.Maybe these unmounted fields could behave the same as a mounted field and a
field.isMountedattribute could be added and then the library would forward the responsibility to the form?A related explicit-deletion case in TanStack Form v1.24.3:
deleteField()removes the field value and metadata but does not re-run form-level validation. In a dynamic currency form with anonMount/onChangevalidator requiring at least one nonzero value, enter EUR=12, then delete EUR:isTouchedgoes from true to false,isPristinefrom false to true, andcanSubmitbecomes true for the now-empty form. Even callingform.validate("change")after deletion setsisValid=false, butcanSubmitstays true because the form is now untouched. There is a second case: edit USD to 5 and back to 0, enter EUR=12, then delete EUR. USD remains dirty (isPristine=false) and validation is stale, so guarding submit with!isPristinealone still allows a zero-only transfer. We worked around both by callingform.validate("change")afterdeleteField()and requiringstate.canSubmit && state.isValidfor the submit button. This is explicit deletion rather than mere unmounting, but seems relevant to the RFC question of how deleted fields affect form-level touched/pristine and validation state.
RFC: What should happen when
FieldandFormGroupunmount?In TanStack Form, a
FieldorFormGroupfollows the lifecycle of the UI component that renders it: it mounts and unmounts with that component. After it unmounts, the form may still retain state and behavior associated with it. This leaves us with an important question: should unmounting only stop the field or group from rendering, or should it also change how it participates in the form?This RFC looks at what should happen to that retained state and behavior once the corresponding UI is no longer mounted.
The problem
Once a field has mounted, the form keeps state associated with it. This includes metadata such as whether the field has been touched, along with any validation errors.
Some field state also contributes to the state of the form as a whole. For example, changing a field sets that field's
isTouchedstate totrue. It also setsform.state.isTouchedtotrue, because the form-level value tells us whether any field has been touched.When an application explicitly deletes or resets a field, it is clear that the field's state is meant to change. The form can update its form-level state at the same time, and those explicit actions give us a clear point at which to decide what should happen to the field's validators and listeners.
Unmounting does not carry the same intent. A field might disappear because the user moved to another step, switched tabs, or scrolled it out of a virtualized view. The field is no longer rendered, but the user did not necessarily delete or reset it. We therefore need to decide whether unmounting should affect only the UI or also the field's role in the form.
The ambiguity
A two-step form makes the issue easier to see. In this example, the first step contains a
namefield and the second step contains the submit button. The code uses React syntax, but the same lifecycle question applies to other UI frameworks:Clicking Next unmounts the
namefield, but its value remains in the form. The field is now absent from the UI while still being part of the form's stored data. What should happen when the user submits from the second step? Should the unmounted field's validator still run? If the user edited the field before moving on, should the form still be considered touched? If the field has a listener, should that listener remain active even though the field is no longer rendered?More generally, we need to decide which parts of an unmounted field should continue to participate in the form:
form.handleSubmit(), or should it be disabled while the field is unmounted?isTouchedinclude every field the form knows about, or only the fields that are currently mounted?The same questions apply to
FormGroup, which also follows the lifecycle of a rendered component.Why this matters
isPristinecould change only because a different set of fields is currently rendered, even if the user did not change any values.The goal of this RFC is to agree on a predictable default for these cases. We would especially like to hear about use cases where mounted and unmounted fields need to behave differently.