[Race condition] Multiple fields with async validators not updating field state in this user interaction
Are you submitting a bug report or a feature request?
Bug Report
What is the current behavior?
If I have two fields on the page that both use async validators, there is a scenario where my first validator function doesn't correctly update the form state. See this sandbox: https://codesandbox.io/s/gracious-payne-6ekgy
To replicate:
- Type something random into field 1
- While field 1 is validating and before the validation function resolves, focus onto field 2 and type "B" into it, which is the value that makes field 2 valid
- Notice that field 1's state remains stuck in
{valid: true}and{validating: true}. - Notice that my form state is
{valid: true}, even though my async validator returns an error and should have updated the form state accordingly
What is the expected behavior?
I would have expected that when I perform the above interaction
- my field 1 validator should have updated field 1s state to
{invalid: true}and{validating: false}after returning an error - my form should be invalid
Sandbox Link
What's your environment?
React final form 6.4 Final form 4.19.1 Happens on my mac in both safari and chrome
Other information
@erikras Just following up on this one, our sign up form is breaking when users move too quickly through our async validator fields
This is still an issue, even with 1 async validator, which is triggered on each keystroke due to react-final-form having no debounce. The previous promises aren't handled correctly in order from what I can see while debugging.
What I see happening in our use-case is:
- first character is entered
- async validator triggers call, returning promise
--
validatingis set to true - second character is entered
- async validator triggers call, returning promise
--
validatingis set to true - first promise returns an error
-- (!)
validatingis set to false, as promise returns, but it's not checked if this was an "old" promise, which makes for buttons to become enabled etc.... so state of form/field is not correct anymore from this point on. - second promise returns an error -- Here state catches up off course, because this is the latest value. We are lucky to have implemented a "cut-off" for previous validation promises, otherwise, their order would mess this whole thing up even more.
So in short, final-form should mind the order of the promises, and not just setting validating to false when one resolves, as that is plain wrong.