Formik: How to use a dynamic validateOnChange value?

Created on 31 Mar 2020  路  5Comments  路  Source: formium/formik

We have a form we want to validate on change only after a user have submitted a form.

We try to fix this warning now: "Cannot update a component from inside the function body of a different component." Which is mentioned in this issue of react on Github https://github.com/facebook/react/issues/18178

With this error we had a solution with a local useState. Which basically looks like this:

const component = () => {
  const [validateOnChange, setValidateOnChange] = useState(false);
  return (
    <Formik
      initialValues={{ one: '', two: '' }}
      validationSchema={validationSchema}
      validateOnChange={validateOnChange}
      validateOnBlur={false}
      onSubmit={handleSubmit}
    >
      {(formikProps: FormikProps<SomeTypes>) => {
        /** validate form on change after one submit count */
        formikProps.submitCount > 0 && setValidateOnChange(true);

        return <FormComponent formikProps={formikProps} />;
      }}
    </Formik>
  );
};

To fix this we currently have a PR for this solution. But I'm not sure as usually props are not mutable. But it does change the prop validateOnChange value..

example here: https://codesandbox.io/s/formik-example-ovi1c

How should we set a value for validate on change on a dynamic way?

Most helpful comment

You may need to add enableReinitialize={true} in order to cause the validateOnChange prop to reinitialize formik.

I'm not certain if that will actually work, but it's a good next step. Please note that enableReinitialize will cause Formik to reinitialize if values change, meaning if you pass a dynamic initialValues obejct to Formik you'll need to make sure it's memoized to prevent meaningless initializations.

Edit: I checked out your sandbox, and you were on the right track with your first attempt. However, you should update the state in an event handler instead of during render, like this:

https://codesandbox.io/s/formik-example-luou6

Note the change to <form onSubmit={} />

All 5 comments

I think this looks like a good solution. In this solution you aren't mutating the props but passing a slice of state as the prop and updating that slice of state.

You could update your conditional to prevent unnecessary updates.
formikProps.submitCount > 0 && validateOnChange === false && setValidateOnChange(true);

One possible solution could be to allow validateOnChange to optionally accept a function that could use props to return if the form should validateOnChange.

It looks like it's not really working. It is changing the validateOnChange prop inside the component, but it's not validating on change...

Ahh, I'd have to dig in the code to verify but I'm assuming that is because validateOnChange gets set on formikBag and can't be changed once initialized.

Maybe check out the onReset function? You could use that to reset the form to the current props plus the updated validateOnChangeProp https://jaredpalmer.com/formik/docs/api/formik#onreset-values-values-formikbag-formikbag--void

You may need to add enableReinitialize={true} in order to cause the validateOnChange prop to reinitialize formik.

I'm not certain if that will actually work, but it's a good next step. Please note that enableReinitialize will cause Formik to reinitialize if values change, meaning if you pass a dynamic initialValues obejct to Formik you'll need to make sure it's memoized to prevent meaningless initializations.

Edit: I checked out your sandbox, and you were on the right track with your first attempt. However, you should update the state in an event handler instead of during render, like this:

https://codesandbox.io/s/formik-example-luou6

Note the change to <form onSubmit={} />

Thanks @johnrom . I was updating the component during the rendering. thanks for your reply and fix! I appreciate it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

najisawas picture najisawas  路  3Comments

emartini picture emartini  路  3Comments

PeerHartmann picture PeerHartmann  路  3Comments

giulioambrogi picture giulioambrogi  路  3Comments

pmonty picture pmonty  路  3Comments