react-hook-form: ReValidateMode 'onChange' doesn't validate after changes?
Describe the bug
Not sure if this is a bug or just a misunderstanding on what reValidateMode does…
If I set mode to onBlur and reValidateMode to onChange I expect the value of an input to be validated for the first time when a blur happens on the input (mode).
Assuming the value is not valid, it is in error state at this point. Now, if I change the value of the input to something that is valid, as soon as the value is valid, I would expect the validation to be triggered again, showing no error anymore, as reValidateMode is set to onChange.
If reValidateMode is set to onBlur as well, I would expect it to only validate again when I blur the field after changing the value to a valid one, showing no errors anymore.
The documentation states:
This option allows you to configure when inputs with errors get re-validated after submit. By default, validation is only triggered during an input change.
The description is a bit confusing, as it mentions re-validated after submit, but this doesn’t make sense, as when I set reValidateMode to onChange there is no submit?
To Reproduce Steps to reproduce the behavior:
- Open Codesandbox with
mode: "onBlur"andreValidateMode: "onChange" - Click on placeholder
lastNameinside of text field - Type in text
Test Name - Click anywhere on the blue background (to blur the text field)
lastName errorappears- Click inside of the
lastNametext field on the right ofTest Name(so that the caret is at the end of the text) - Press the backspace key until
Nameis not there anymore (resulting inTestwith space at the end being the value of the text field)
Codesandbox link https://codesandbox.io/s/react-hook-form-useform-template-t597v?file=/src/index.js
Expected behavior
At this point, I would expect the error lastName error to disappear, since the lastName text field is now valid (Test contains 5 characters, limit is 5) and an onChange event happened (from pressing the backspace key the last time).
Actual behavior
The error lastName error is still present and only disappears when clicking anywhere on the blue background to blur the text field. I would only expect this to happen if reValidateMode was set to onBlur as well.
Desktop (please complete the following information):
- OS: macOS
- Browser: Chrome
- Version 83
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 11
- Comments: 26 (14 by maintainers)
@bluebill1049 That’s brilliant. Turned out it’s pretty easy (and rather clean!) to make the workaround I need to satisfy my UX requirements. I have to set both
modeandreValidateModeto'onBlur'though, and thentriggerthe validation manuallyonChangeonly if the control is invalid (has any errors).I’ll simply leave my CSB here just in case future readers might find it useful: https://codesandbox.io/s/react-hook-form-v6-triggervalidation-forked-cbfvt?file=/src/index.js
Thanks again, Bill!! 😃
I’m glad that I came across this issue one month later 'cause actually I want to implement a UX in exactly the same line of theorem as @martinfrancois 🙂
— ✂️ snip ------ There are a couple rules of thumb that guide how we implement validation triggers:
onBlur)onChange)On the surface, these rules can seem slightly contradictory. Do not validate until blur, but validate on change? However, there is a subtlety involved based on the current field validation status. If the field is already invalid, then we should update the validation results on change, without waiting for focus to leave. But if the field is was previously valid or it hasn’t yet been validated, then we should wait until focus leaves the field before updating the validation results for the field. This approach improves usability and decreases frustration for the user. — ✂️ snap ------
It’s so unfortunate that RFH would need a breaking change if this “ideal” behaviour were to be introduced. 😕 But thank you so much @bluebill1049 for such a amazing masterpiece, and for suggesting this workaround:
I will try to follow this suggestion and will come back again if I have any questions ✨😁
Ahhh I see… So if
reValidateModekind of changes themodeto be equal to what is set toreValidateMode(temporarily) after the first time the form was submitted?On another note in this case, would it be possible somehow to configure a behavior like this? So that the field would be validated
onBlurfirst, and after the error appeared on the field it will be validatedonChange? I see this as kind of a usability best practice, as whenmodewasonChangein the first place, it would be confusing for the user, as for example in the case of an email field, as soon as they start typing the first letter it would already tell them the email they entered is invalid, prompting them to think they did something wrong, while they just didn’t finish typing yet. After the user blurs the field, they “confirm” that they are done, and then it shows the error. If the user now refocuses the field to make the change (let’s say they have two@instead of one) and remove the second@they should get immediate feedback by removing the error, showing them the input is now valid. It would be annoying if a user had to first blur the text field again to see if it’s correct afterwards, especially since the error is still visible before they blurred the field causing them to believe there is still something wrong. I see a lot of sites who have forms that implement a behavior like this.Concerning adapting the docs to be more self-explanatory, maybe we could change the doc to say something along the lines of:
One thing I could see would be either changing the behavior to apply
reValidateModeafter the first time there is an error in general (not only after submitting). For me, this feels more logical, as withmodeyou define when the first validation happens, andreValidationMode(just from the terms) would mean for me when the input should get re-validated after an error (in general). By making this change, this would lead in the same behavior as it was before whenmodeasonSubmitis used. For others of course, it would be different, which would imply a breaking change. I’m just trying to think of cases for example where one would want to havemodeas something else thanonSubmitwhich then would want to changereValidateModewith the current behavior, I can’t think of any use case that would make sense, but I may be missing something.Thanks for your detailed feedback in terms of when to trigger validation. I don’t think we will make any change to the validation behavior as this is most likely lead to a breaking change. however, RHF is flexible, you can set both
modetoonSubmitand trigger validation accordingly, or simply always trigger theerrorsand use form state to filter when to displayerrors. in terms of doc improvement please send a PR, we are happy to review and update it.I think for your use case (unique), it’s better to build your validation logic with
triggerin terms of when validation should betriggerand set bothmodeandreValidateModeto ‘onSumbit’.I will release a minor version soon, need to update the changelog and docs.
And yes I read it, I’m just not sure if maybe the docs are not clear enough or I just misunderstood them.
@bluebill1049 sorry, you may be right, I could have forgotten to save the CSB, it should be correct now: https://codesandbox.io/s/react-hook-form-useform-template-t597v?file=/src/index.js