final-form / react-final-form

🏁 High performance subscription-based form state management for React
https://final-form.org/react
MIT License
7.38k stars 480 forks source link

Fields are unregistered when not in the DOM #639

Open jessicamann opened 5 years ago

jessicamann commented 5 years ago

Are you submitting a bug report or a feature request?

Bug report

What is the current behavior?

Field are unregistered, causing meta data (dirty/valid/etc) to be lost, when they are removed from the DOM. The meta data is regained once the field is brought back into the DOM.

See the code sandbox attached for how the Button cannot property stay enabled when the collapsible panel has been closed once a field value is adjusted.

Steps to reproduce:

  1. Open "Address" panel, then type in any value. Notice that the button is now enabled.
  2. Collapse "Address" panel. Notice that:
    • the button is now disabled even though fields have been modified.
    • form is considered pristine even though fields have been modified.
    • "dirtyFields/visited/modified/touched" under form state is empty though address was modified
  3. Open "Address" panel. Notice that:
    • expected form states comes back
    • button is now property enabled

What is the expected behavior?

Fields remain registered upon removal from the DOM, ensuring other subscribers access to it and the form's values and meta states.

Removing elements from the DOM when not in view can be to optimize view performance; it is not necessarily an intent to remove the field from the form.

Sandbox Link

https://codesandbox.io/s/expansion-panel-with-field-zusgx

What's your environment?

react-final-form: 6.3.0 final form: 4.18.5

nosovsh commented 4 years ago

That completely makes sense. One more common use case that can not be implemented now: if you want to show error icon in the header of the collapsed panel to show that there are some fields with errors inside it. But of course, you want to show this icon only if this field was touched, otherwise freshly opened form will be already filled with error icons. Currently there is no way to know whether a field was already touched when you close a panel (-> field dom destroyed -> field is unregistered -> field meta is lost)

nosovsh commented 4 years ago

Even more basic use case. If your form is split by multiple tabs/collapsible panels/modal windows/whatever that can be destroyed and recreated.

  1. User opens one tab, clicks into a required field -> it is touched -> error is shown.
  2. then he opens another tab
  3. Comes back to the first one and doesn't see an error message for the first required field because the field's meta is lost
Mottoweb commented 2 years ago

I am also getting the error removed from the form state, while submit error is being persisted.

Dragomir-Ivanov commented 2 years ago

@Mottoweb The way I solve this is just keep dummy registered all fields, all the time.

const Dummy = () => {
useField("fieldA")
useField("fieldB")
....
}
<Form ...>
<Dummy />
....
</Form>