Can someone provide an example of how to migrate isInitialValid to initialErrors? I wrote about my current implementation here #1454.
I'm am implementing v2 and getting the deprecation message for isInitialValid. Any specific example on how to convert this would be great.
I'm currently using dirty state to check if form was changed since initialValues.
<Formik {...props}>
{({ dirty }) => (
<form>
<Button isDisabled={!dirty}>Send</Button>
</form>
)}
</Formik>
@Kinbaum have you tried valideOnMount ?
@domeknn it works but causes an uncanny behavior. It flicks/blinks the form, quickly updating isValid from true to false.
@VitorLuizC nice catch, didnt saw this! Tried to use validateSync from Yup, but it throws error :/ Even that validateOnMount didnt change isValidating. With dirty also can be problem while you're autofilling form (like getting delivery address from database and put into form). 馃槩
@VitorLuizC nice catch, didnt saw this! Tried to use
validateSyncfrom Yup, but it throws error :/ Even that validateOnMount didnt changeisValidating. Withdirtyalso can be problem while you're autofilling form (like getting delivery address from database and put into form). 馃槩
Yeap, I had to use enableReinitialize and put my initialValues in a useMemo. Seems fixed now, but is a little more boilerplate code than before.
const initialValues = useMemo(
() => ({
name: user?.name ?? '',
email: user?.email ?? '',
...
}),
[user]
);
<Formik
enableReinitialize
initialValues={initialValues}
>
{
({ dirty, isValid }) => (
<Button isDisabled={dirty && !isValid}>Send</Button>
)
}
</Formik>
@VitorLuizC Okay, but what's when in initialValues you got valid object? Button is still disabled ?
Yeap. Our UX tell us to keep it disabled and only enable when user change change it.
@jaredpalmer
This is the only solution that seems to work for me. Unfortunately, I still have to use the deprecated isInitialValid. validateOnMount works initially when the form mounts, but when I go forward and backward between pages it doesn't reflect the validationSchema for the current page. In order for it to reflect properly, I have to touch a field, then blur off of it.
const [ formValues, setFormValues ] = useState(initialValues);
// ... removed extra code for brevity
function nextPage({ values }) {
setCurrentPage(Math.min(currentPage + 1, children.length - 1));
setFormValues(values);
}
function previousPage({ values }) {
setCurrentPage(Math.max(currentPage - 1, 0));
setFormValues(values);
}
```jsx
isInitialValid={ () => (schema ? schema.isValidSync(formValues) : true) }
enableReinitialize={ true }
validationSchema={ schema }
onSubmit={ handleSubmit }>
Here is how I am showing / hiding the next button
```jsx
<Button
color="primary"
variant={ !isLastPage && innerProps.isValid ? null : 'hidden' }
action={ () => nextPage(innerProps) }>
{ activePage.props.nextLabel || 'Next' }
</Button>
<Formik
initialValues={ formValues }
enableReinitialize={ true }
validateOnMount={ true }
validationSchema={ schema }
onSubmit={ handleSubmit }>
I've also tried to check the errors object to see if it's empty in order to toggle the next button.
<Button
color="primary"
variant={ !isLastPage && Object.entries(innerProps.errors).length === 0 ? null : 'hidden' }
action={ () => nextPage(innerProps) }>
{ activePage.props.nextLabel || 'Next' }
</Button>
Works initially, but going forward and back between pages causes the errors object to be behind in state.
So if I:
errors object will contain errors from page 2, so the next button doesn't show up on page 1.Like I said, the only thing that I've been able to get working is to do isInitalValid with synchronous schema validation.
Hi, @Kinbaum.
I just faced the same issue with initial validation. Tried to use initialTouched with the invalid keys object and it works to me.
Example:
<Formik
initialValues={initialValues}
validationSchema={FormSchema}
initialTouched={{ firstName: true }}
initialErrors={{ firstName: 'Required' }}
onSubmit={ handleSubmit }
>
The tip from @domeknn solved for me. I'm only using validateOnMount.
<Formik validateOnMount {...props}>
{({ isValid }) => (
<form>
<button disabled={!isValid}>Send</disabled>
</form>
)}
</Formik>
Most helpful comment
@jaredpalmer
This is the only solution that seems to work for me. Unfortunately, I still have to use the deprecated
isInitialValid.validateOnMountworks initially when the form mounts, but when I go forward and backward between pages it doesn't reflect the validationSchema for the current page. In order for it to reflect properly, I have to touch a field, then blur off of it.Working but deprecated
```jsx
initialValues={ formValues }
isInitialValid={ () => (schema ? schema.isValidSync(formValues) : true) }
enableReinitialize={ true }
validationSchema={ schema }
onSubmit={ handleSubmit }>
Not working
I've also tried to check the
errorsobject to see if it's empty in order to toggle the next button.Works initially, but going forward and back between pages causes the
errorsobject to be behind in state.So if I:
then the
errorsobject will contain errors from page 2, so the next button doesn't show up on page 1.Like I said, the only thing that I've been able to get working is to do
isInitalValidwith synchronous schema validation.