React formik 验证错误 Api 每次在其他字段验证时呈现

React formik Validation Error Api Renders Every Time when other field validate

我已经创建了一个注册表单我试图在 Blur 上验证表单并且其中有一个与后端 Apis 的电子邮件检查,我在验证任何其他情况时遇到问题邮件检查 API 呈现每个时间 我尝试使用 onBlur 和 onChange validation false 这种情况下工作正常,但我需要 onBlur 验证,任何想法

感谢帮助


const CompanyRegister = (props) => {
  const classes = useStyles();
  var [mailError, setMailError] = useState(false);

  const initialValues = {
    name: "",
    website: "",
    addressLine1: "",
    city: "",
    state: "",
    mail: "",
  };

  const validationSchema = yup.object({
    name: yup.string().strict().trim().required("Enter the ComapnyName"),
    website: yup
      .string()
      .matches(
        /((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/,
        "Enter correct url!"
      )
      .strict()
      .trim()
      .required("Enter the Website"),
    pincode: yup.number("Invalid pincode").positive("Invalid pincode"),
    phone: yup.number("InValid Phone Number"),
    altPhone: yup.number("InValid Phone Number"),
    mail: yup
      .string()
      .email("Enter correct Format")
      .strict()
      .trim()
      .required("Enter the Correct Email"),
  });

  const validCheck = (data) => {
    var mailData = { mail: data };
    axios.post(baseurl + "companymailcheck", mailData).then((res) => {
      if (res.data == "Invalid") {
        setMailError(true);
      } else {
        setMailError(false);
      }
    });
  };

  const onSubmit = (data) => {
    axios
      .post(baseurl + "companyregisteration", data)
      .then((res) => {
        history.push(`/login`);
        toast.success("Successfully Created");
      })
      .catch((err) => {
        toast.error("Some Thing Error");
      });
  };

  return (
    <>
      <div className={classes.back}>
        <Link to="/">Home</Link>
      </div>
      <Container component="main" className={classes.layout}>
        <div className={classes.paper}>
       
          <Typography component="h1" variant="h5">
            Register
          </Typography>
          <Formik
            initialValues={initialValues}
            onSubmit={onSubmit}
            validateOnChange={false}
            validateOnBlur={true}
            validationSchema={validationSchema}
          >
            {({ values, isValid }) => {
              return (
                <Form autoComplete="off">
                  <Grid container spacing={4}>
                    <Grid item xs={12} sm={6}>
                      <Field
                        as={TextField}
                        name="name"
                        fullWidth
                        label="Company Name"
                        autoFocus
                        required
                      />
                      <ErrorMessage name="name">
                        {(error) => (
                          <div className={classes.error}>{error}</div>
                        )}
                      </ErrorMessage>
                    </Grid>
                    <Grid item xs={12} sm={6}>
                      <Field
                        as={TextField}
                        name="website"
                        fullWidth
                        label="Website"
                        required
                      />
                      <ErrorMessage name="website">
                        {(error) => (
                          <div className={classes.error}>{error}</div>
                        )}
                      </ErrorMessage>
                    </Grid>
                    <Grid item xs={12} sm={12}>
                      <Field
                        as={TextField}
                        name="addressLine1"
                        type="text"
                        fullWidth
                        label="Address Line1"
                      />
                    </Grid>
                 
                  
                    <Grid item xs={12} sm={6}>
                      <Field
                        as={TextField}
                        name="mail"
                        fullWidth
                        label="Mail"
                        required
                        validate={() => validCheck(values.mail)}
                      />
                      <ErrorMessage name="mail">
                        {(error) => (
                          <div className={classes.error}>{error}</div>
                        )}
                      </ErrorMessage>
                      {mailError ? (
                        <span style={{ color: "red" }} id="errormessage">
                          Mail Already There!
                        </span>
                      ) : null}
                    </Grid>

                    <Button
                      type="submit"
                      fullWidth
                      variant="contained"
                      color="primary"
                      className={classes.submit}
                      disabled={!isValid || mailError}
                    >
                      Register
                    </Button>
                  </Grid>
                </Form>
              );
            }}
          </Formik>
        </div>
      </Container>
    </>
  );
};

export default CompanyRegister;

只要在表单提交期间执行验证没问题,那么我会扩展 onSubmit 并在那里进行检查。

您可以使用第二个参数 return 包含所有相关 setter 的 FormikBag 来正确地使表单字段无效。参考:https://formik.org/docs/api/formik#onsubmit-values-values-formikbag-formikbag--void--promiseany

在这种情况下,我会使用 setFieldError(field, message)。参考:https://formik.org/docs/api/formik#setfielderror-field-string-errormsg-string--void

<Formik initialValues={initialValues}
        validationSchema={validationSchema}        
        onSubmit={(values, {setFieldError}) => {
            return validateMail(values.mail)
                 .then(() => {
                   // all good - continue with your submit handler
                   return onSubmit(values)
                 }) 
                 .catch(error => {
                   // something wrong? validate the error response + validation message OR set it statically.
                   setFieldError('mail', 'Mail Already There!')
                 }) 
        }}
          >