简体   繁体   English

React formik 表单验证:如何最初禁用提交按钮

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

Below is my React form validation code in which I am using formik .下面是我使用formik React表单验证代码。 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.我检查了文档,但没有看到任何明显的东西。

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:如果您想在表单加载时最初禁用submit按钮,您可以使用Formikdirty : boolean属性,如下所示:

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:如果您想在所有字段值都有效之前禁用submit按钮,那么您可以使用isValid: boolean ,其工作方式如下:

Returns true if there are no errors (ie the errors object is empty) and false otherwise.如果没有错误(即错误对象为空),则返回 true,否则返回 false。

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)}

要最初禁用按钮,只需检查触摸对象是否为空并保持这种方式,直到所有字段都使用!isValid进行验证

disabled={!isValid || (Object.keys(touched).length === 0 && touched.constructor === Object)}

Formik keeps track of field values and errors however exposes them for your use, this used to be done via formProps using the render props pattern however now seems to be part of the formik variable returned by the useFormik hook. Formik 会跟踪字段值和错误,但会公开它们供您使用,这曾经是通过 formProps 使用渲染道具模式完成的,但现在似乎是 useFormik 钩子返回的 formik 变量的一部分。

I would recomend to start by removing the initial values to a constant.我建议首先将初始值删除为常量。 Then you need to access the formik's error object.然后你需要访问formik的错误对象。 I have not done this using the new hook syntax, however, looking at the docs I would expect "formik.errors" to work (this is exposed in formProps.errors using render props).我没有使用新的钩子语法来完成这个,但是,查看我希望“formik.errors”能够工作的文档(这在 formProps.errors 中使用渲染道具公开)。 Finally the submit buttion disabled should be a check that either formik.values is equal to the initial values OR the errors object is not empty.最后,禁用提交按钮应该检查 formik.values 是否等于初始值或错误对象不为空。

You can add validateOnMount and set it to true您可以添加validateOnMount并将其设置为 true

const formik = useFormik({
    initialValues: {
      validateOnMount: true, // <================= Add this
      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);
    }
  });

Use on button在按钮上使用

disabled={!formik.isValid}

I'm using我正在使用

"formik": "^2.2.6" "formik": "^2.2.6"

and in my case I did it like this.就我而言,我是这样做的。 I was not interested to show the messages in the validation messages in initial so I did in this way.我没有兴趣在初始时显示验证消息中的消息,所以我这样做了。

I'm using class based components我正在使用基于类的组件

<Formik
......
validateOnBlur={true}
validateOnChange={true}
{({handleChange, values, touched, errors, handleBlur }) => (<>
    ..........
    <Form.Control
        placeholder="Name"
        type="text"
        name="field_dba"
        value={values.name}
        onChange={handleChange}
        onFocus={handleBlur} // It plays a role to change the touched property 
        isInvalid={touched.name && !!errors.name}
        isValid={!errors.name}
        className="form-input"
    />
    <label className="modal-lab">Name *</label>
    // Here i'm checking the field is touched or not 
    {touched.name ? <Form.Control.Feedback type="invalid" className="text-capitalize"> {errors.name} </Form.Control.Feedback> : null}

at the end for disabling the button till it's all validated.最后禁用按钮,直到全部验证。 I'm using this我正在使用这个

<button disabled={Array.isArray(errors) || Object.values(errors).toString() != ""} type="submit"> Submit </button>

If this will work with same version please do a upvote.如果这适用于相同的版本,请点赞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM