react-final-form icon indicating copy to clipboard operation
react-final-form copied to clipboard

<FormSpy /> onChange fires several times when fields are added to the form conditionally and in an iteration

Open gaborluk opened this issue 5 years ago • 1 comments

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 <FormSpy /> 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 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 <option />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 <Field />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?

<FormSpy />'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.

gaborluk avatar Feb 15 '20 17:02 gaborluk

Any update on this? I'm also having the same issue in "react-final-form": "^6.5.3",.

brionmario avatar Oct 12 '23 05:10 brionmario