React formik form validation: How to initially have submit button disabled

user8463989 picture user8463989 · Dec 22, 2019 · Viewed 18.5k times · Source

Below is my React form validation code in which I am using formik. By default when the form loads, I want to keep the submit button disabled:

import { useFormik } from "formik";
import * as Yup from "yup";

const formik = useFormik({
    initialValues: {
      firstName: "",
      lastName: "",
      email: ""
    },
    validationSchema: Yup.object({
      firstName: Yup.string()
        .max(15, "Must be 15 characters or less")
        .min(3, "Must be at least 3 characters")
        .required("Required"),
      lastName: Yup.string()
        .min(3, "Must be at least 3 characters")
        .max(20, "Must be 20 characters or less")
        .required("Required"),
      email: Yup.string()
        .email("Invalid email address")
        .required("Required")
    }),
    onSubmit: values => {
      handleSubmit(values);
    }
  });

I have tried to use this on my button:

 disabled={!formik.isValid}

But it only actually works if I try to submit the form. So, if I leave the form blank and hit submit, all the validation errors show up and then the button is disabled. But, it should be disabled already from the start. I checked the documentation but didn't see anything obvious there.

Answer

Rahul Gupta picture Rahul Gupta · Jan 10, 2020

If you want to keep the submit button disabled initially when the form loads, you can use the use the dirty : boolean property of Formik something as below:

disabled={!formik.dirty}

If you want to keep the submit button disabled until all the field values are valid then you can use isValid: boolean which works as below:

Returns true if there are no errors (i.e. the errors object is empty) and false otherwise.

So you may use it as:

disabled={!formik.isValid}

Now, if you want the submit button to be disabled until all the fields are valid and if the fields values have been changed from their initial values then you would have to use both of the above attributes in conjunction as below:

disabled={!(formik.isValid && formik.dirty)}