final-form / final-form/react-final-form
<FormSpy /> onChange fires several times when fields are added to the form conditionally and in an iteration
- Dominant language
- JavaScript
- Stars
- 7.4k
- Forks
- 497
- PR merge metrics
- No merged PRs in 30d
Description
### Are you submitting a **bug report** or a **feature request**?
Bug report.
### What is the current behavior?
I was writing a form generator component when I ran into this issue. It seems like the `onChange` handler of `` fires way too many times during the rendering of the form if some of the fields are added in an iteration, and their rendering is limited by a condition.
It's much easier to demonstrate the issue than to describe it, so I have created a [CodeSandbox](https://codesandbox.io/s/serene-sammet-0odqq) with an attempt to reasonably isolate the issue.
Some things to note:
- I'm using `touched` to demonstrate the issue not because it is only relevant for `touched`, but because `touched` contains all the currently recognized fields at all times, so it's shown well which fields are currently registered by React Final Form at the moment of the `onChange` handler firing.
- On initial load, the `onChange` handler fires 3 times per field: once with the originally known fields* only (`{trainer}`), once with the originally known fields plus each new field (`{trainer, pokemon-1}`, `{trainer, pokemon-2}`, `{trainer, pokemon-3}`), and once with the originally known fields plus all new fields iteratively added (`{trainer, pokemon-1}`, `{trainer, pokemon-1, pokemon-2}`, `{trainer, pokemon-1, pokemon-2, pokemon-3}`).
- Interestingly, a similar behavior is seen in reverse, for the lack of a better term, when the "master" field (`trainer`) is set to an empty value. In general, I have observed this type of issue with ``s whose value is empty or `''`.
- Of course, the handler will fire dozens if not hundreds of times as the number of fields is increased.
_* By originally known fields, I mean the fields that have been ready to be rendered since the very first render cycle, not being blocked by a falsy condition initially._
I'm not under the impression that I understand the issue well, but I have observed a few things:
- When `defaultValue` (and `initialValue`) props are removed from ``s, the behavior doesn't present itself.
- When a condition relying on `values` is not limiting the rendering of certain fields (see `isTrainerSelected(values)`), the behavior also doesn't present itself.
I hope this information is sufficient for reproducing and fixing the issue.
### What is the expected behavior?
``'s `onChange` handler fires only once per form, as opposed to gradually firing when a new field is internally encountered, multiple times for each.
### Sandbox Link
https://codesandbox.io/s/serene-sammet-0odqq
### What's your environment?
React Final Form 6.3.5, Final Form 4.18.7, Windows, Chrome.
Contributor guide
Assessment
This issue has not been assessed yet.