When validateOnMount is true, initial value for isValid is 'true', then validation occurs on initial values (which could set isValid to 'false').
Screenshot taken from reproducible example - see console for inconsistency - isValid has a different value, for the same form value (empty string in the example):

The first render should return the result of validating the initial values for isValid.
https://codesandbox.io/s/formik-codesandbox-template-kegrs
Would this problem be solved by setting initial errors? I believe possibly, although that would require running validation manually, defeating the purpose of validateOnMount.
The example is a simplification - application code has a far more complex validation schema + more initial values.
| Software | Version(s) |
| ---------------- | ---------- |
| Formik | 2.1.1 |
| React | 16.12.0 |
| TypeScript | - |
| Browser | Codesandbox? && Chrome |
| npm/Yarn | 6.13.4 |
| Operating System | MacOSX 10.15.2 |
I'd like to help with this
Go for it!
I'd like to help with this
Any progress on this?
Yeah. Putting up a PR in a couple of days
@omkar-joshi is there any progress on this? If you're still working on the PR, I would really appreciate if you could explain any workarounds for this issue at this time. Also, is there any way to prevent Formik from setting errors after running validateOnMount. I would like to set the isValid value, but not have errors on the fields. Thanks for your anticipated help.
Yeah. Putting up a PR in a couple of days
Hi @omkar-joshi any update on this? appreciate your contribution towards OSS.
Is it just a case of using validateFormWithHighPriority instead of validateFormWithLowPriority? https://github.com/jaredpalmer/formik/blob/f117c04738ed218b5eb8916d7189e0849962d50d/packages/formik/src/Formik.tsx#L366-L370
馃憢 Hi @semopz I've been looking into this a bit this weekend, and I don't think high/low priority will fix this issue unfortunately. Both validate form functions (withLow... / withHigh...) call runAllValidations which runs asynchronously - so from mount until that promise resolves, isValid will be true. This can cause an unideal user experience, specifically if isValid is used to drive form appearance, for example disabling the submit button. As a consumer of formik, I need to know what to render while validation on mount is running 馃
Some possible solutions (in user-land or in the library) I can think of are:
initialErrors, then renderisInitialValid - to set isValid whilst validation on mount is runningisValidating to true initially, then use this value to determine what to render. (I've coded this here to show how)Not really sure how to proceed with this, I understand to an extent why isInitialValid was deprecated, but also think removing it isn't serving us well in this scenario.

Here are a few options in my view:
Option 1:
Option 2:
isInitialValid and only issue a warning if the user uses _more than one_ of { isInitialValid, validateOnMount, and initialErrors}, which could result in conflicting validation states & thus render flashing. IMO this is the simplest and best option. But it does not account for cases where we legitimately need to do an async call in order to compute whether the initial state is valid. (But really, do these cases even exist in the wild? I can't think of a real-world example where an async-validated form doesn't know its initial validation state on initial render. In fact it seems like in "80%" of cases, the initial state is invalid, so it seems like isInitialValid should have been defaulting to false this whole time!)If people think that Option 2 makes sense, I can send a PR.
I stick on option 2 and use isInitialValid. It fits my needs, it's a simple props to disable a submit button before user completes fields 馃槆
Ultimately the state of isValid cannot be known until validation completes, unless it is explicitly provided (which defeats the purpose of validateOnMount).
Where I have experienced this issue, and likely where many others have, is in trying to control enabled/disabled state of a submit button.
Typically the button would be disabled while validations are running. The logic would therefore be disabled={isValidating || !isValid}.
The problem is that isValidating is false on initial render even when validateOnMount is set to true. This seems counterintuitive. Having isValidating default to true when validateOnMount is true would likely allow most of us to work around this issue.
Status?
Most helpful comment
Ultimately the state of
isValidcannot be known until validation completes, unless it is explicitly provided (which defeats the purpose ofvalidateOnMount).Where I have experienced this issue, and likely where many others have, is in trying to control enabled/disabled state of a submit button.
Typically the button would be disabled while validations are running. The logic would therefore be
disabled={isValidating || !isValid}.The problem is that
isValidatingisfalseon initial render even whenvalidateOnMountis set to true. This seems counterintuitive. HavingisValidatingdefault totruewhenvalidateOnMountistruewould likely allow most of us to work around this issue.