简体   繁体   English

是的,“notRequired”方法似乎在我的表单验证中不起作用

[英]Yup 'notRequired' method doesn't seem to be working in my form validation

I am using Yup to validate my form fields.我正在使用 Yup 来验证我的表单字段。

I want the user to paste their instagram URL into the input field.我希望用户将他们的 instagram URL 粘贴到输入字段中。 It is not a required field but if they do start to type, the string must match the regex.这不是必填字段,但如果他们确实开始输入,则字符串必须与正则表达式匹配。 The regex works, however the 'invalid url' message still displays if the user doesn't type anything, even although the field should not be required.正则表达式有效,但是如果用户没有键入任何内容,即使该字段不应该是必需的,仍然会显示“无效 url”消息。 I have tried the following but it still doesn't work.我尝试了以下方法,但仍然无法正常工作。 Any suggestions?有什么建议么?

 const validationSchema = Yup.object().shape({
    instagram: Yup.string()
      .notRequired()
      .matches(
        /(?:(?:http|https):\/\/)?(?:www.)?(?:instagram.com|instagr.am)\/([A-Za-z0-9-_]+)/im,
        'invalid url'
      ),
  });

In this case you need to use the .nullable() method.在这种情况下,您需要使用.nullable()方法。

Try this :试试这个 :

 const validationSchema = Yup.object().shape({
    instagram: Yup.string()
      .matches(
        /(?:(?:http|https):\/\/)?(?:www.)?(?:instagram.com|instagr.am)\/([A-Za-z0-9-_]+)/im,
        'invalid url'
      )
      .nullable(),
  });

Long time no see!好久不见! I'm not sure if you're using a form state manager or not, but a lot of people seem to use Formik with Yup.我不确定您是否使用了表单状态管理器,但很多人似乎都将Formik与 Yup 一起使用。

Take a look at this working example using Formik with Yup :看看这个使用Formik 和 Yup 的工作示例:

用 Yup 编辑 Formik

Demo Code :演示代码

import * as React from "react";
import { Formik } from "formik";
import * as Yup from "yup";

const validationSchema = Yup.object().shape({
  instagram: Yup.string()
    .notRequired()
    .matches(
      /(?:(?:http|https):\/\/)?(?:www.)?(?:instagram.com|instagr.am)\/([A-Za-z0-9-_]+)/im,
      "Invalid Instagram URL. Example: http(s)://instagram.com/janedoe"
    )
});

const ValidatedInstagramForm = () => {
  const handleFormSubmit = (values, { setSubmitting }) => {
    alert(
      `Validated form was submitted with:\n${JSON.stringify(values, null, 4)}`
    );
    setSubmitting(false);
  };

  return (
    <Formik
      initialValues={{ instagram: "" }}
      onSubmit={handleFormSubmit}
      validationSchema={validationSchema}
    >
      {({
        errors,
        handleBlur,
        handleChange,
        handleSubmit,
        isSubmitting,
        values,
        touched
      }) => (
        <form className="form" onSubmit={handleSubmit}>
          <div className="input-container">
            <label className="label" htmlFor="instagram">
              Instagram
            </label>
            <input
              name="instagram"
              type="text"
              placeholder="Enter your instagram (optional)..."
              value={values.instagram}
              onChange={handleChange}
              onBlur={handleBlur}
              className="input"
              style={{
                background:
                  errors.instagram && touched.instagram
                    ? "rgba(255, 0, 0, 0.25)"
                    : "",
                borderColor: errors.instagram && touched.instagram ? "red" : ""
              }}
            />
            {errors.instagram && touched.instagram && (
              <div className="error">{errors.instagram}</div>
            )}
          </div>
          <button className="button" type="submit" disabled={isSubmitting}>
            Submit
          </button>
        </form>
      )}
    </Formik>
  );
};

export default ValidatedInstagramForm;

If you're not using a form state manager, then you could always manually validate the input on form submit instead of on input change:如果您没有使用表单状态管理器,那么您始终可以手动验证表单提交而不是输入更改的输入:

编辑手动验证输入

Demo Code :演示代码

import * as React from "react";

const ValidatedInstagramForm = () => {
  const [value, setValue] = React.useState("");
  const [error, setError] = React.useState("");

  const handleChange = ({ target: { value } }) => {
    setValue(value);
    setError("");
  };

  const isValidInput = (value) => {
    if (!value) return "";

    return /(?:(?:http|https):\/\/)?(?:www.)?(?:instagram.com|instagr.am)\/([A-Za-z0-9-_]+)/im.test(
      value
    )
      ? ""
      : "Invalid Instagram URL. Example: http(s)://instagram.com/janedoe";
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    const error = isValidInput(value);

    if (!error)
      alert(
        `Validated form was submitted with:\n${JSON.stringify(
          { instagram: value },
          null,
          4
        )}`
      );
    else setError(error);
  };

  return (
    <form className="form" onSubmit={handleSubmit}>
      <div className="input-container">
        <label className="label" htmlFor="instagram">
          Instagram
        </label>
        <input
          name="instagram"
          type="text"
          placeholder="Enter your instagram (optional)..."
          value={value}
          onChange={handleChange}
          className="input"
          style={{
            background: value && error ? "rgba(255, 0, 0, 0.25)" : "",
            borderColor: value && error ? "red" : ""
          }}
        />
        {value && error ? <div className="error">{error}</div> : null}
      </div>
      <button className="button" type="submit" disabled={error}>
        Submit
      </button>
    </form>
  );
};

export default ValidatedInstagramForm;

In fact, there are two definitions of .matches()<\/code> method :其实.matches()<\/code>方法有两种定义:

  • string.matches(regex: Regex, message?: string | function)<\/code><\/li>
  • string.matches(regex: Regex, options: { message: string, excludeEmptyString: bool })<\/code><\/li><\/ul>

    Both are matching the Regexp passed in argument, but the second one short circuits the test when the value is an empty string (notice that now the message should be in the options object).两者都匹配传入参数的正则表达式,但是当值为空字符串时,第二个会使测试短路(注意现在消息应该在选项对象中)。

    So in your case, you should use the second definition.所以在你的情况下,你应该使用第二个定义。 Here is the correct code (you don't need to include .notRequired<\/code> method) :这是正确的代码(您不需要包含.notRequired<\/code>方法):

     const validationSchema = Yup.object().shape({ instagram: Yup.string() .matches( \/(?:(?:http|https):\\\/\\\/)?(?:www.)?(?:instagram.com|instagr.am)\\\/([A-Za-z0-9-_]+)\/im, { message: 'invalid url', excludeEmptyString: true, } ), });<\/code><\/pre>"

I had several problems in this matter, so this is my take, and solution.我在这件事上有几个问题,所以这是我的看法和解决方案。 eg Allowed null, or if they were filled in then they had to have an min length.例如,允许 null,或者如果它们被填写,那么它们必须有一个最小长度。

    taxid: Yup.string()
      .nullable()
      .notRequired()
      .transform(x => x === '' ? undefined : x)
      .min(5, 'TaxID must be at least 5 characters'),
    corpname: Yup.string()
      .nullable()
      .notRequired()
      .transform(x => x === '' ? undefined : x)
      .min(2, 'Company name must be at least 2 characters'),
    postno: Yup.string()
        .required('Post number is required')
        .min(4, 'Post number must be at least 4 characters'),

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

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