1

我在 react-boostrap 表单上构建了 formik 表单。我有一个自定义的 onchange 来处理输入。问题是即使表单字段中有值也会引发验证错误。此外,如果键入了某些值,则错误消息不会消失。我想验证根本不起作用。请帮助我。

这是 react-bootstrap 表单的代码https://react-bootstrap.github.io/components/forms/#forms-validation-libraries

import React from "react";
import * as yup from "yup";

export default function StepByStepForm() {
  const [myForm, setMyForm] = useState({});

  const handleInput = (e) => {
    const value = e.target.value;
    const name = e.target.name;
    setMyForm((prev) => ({
      ...prev,
      [name]: value,
    }));
  };

  const form1schema = yup.object({
    company_name: yup.string().required(),
  });

  function Step1Form() {
    return (
      <Formik validationSchema={form1schema}>
        {({
          touched,
          isValid,
          isInvalid,
          errors,
          handleBlur,
          handleChange,
          values,
          validateForm,
        }) => (
          <Form noValidate className="formstep1">
            <Form.Group controlId="addCompany">
              <Form.Label>Company Name*</Form.Label>
              <Form.Control
                name="company_name"
                type="text"
                value={myForm.company_name}
                onChange={handleInput} // have my custom handling
                isInvalid={!!errors.company_name}
              />
              <Form.Control.Feedback type="invalid">
                {errors.company_name}
              </Form.Control.Feedback>
            </Form.Group>

            <div className="step-progress-btn">
              <Button variant="primary" onClick={() => validateForm()}>
                Validate
              </Button>
            </div>
          </Form>
        )}
      </Formik>
    );
  }

  return <div>Step1Form()</div>;
}
4

2 回答 2

0

问题是 Formik-Yup 需要 onChange={handleChange} 来验证

如果您在 handleChange 之上有自定义或附加功能,那么您需要在 handlechange 之上添加事件监听器

import React from "react";
import * as yup from "yup";

export default function StepByStepForm() {
  const [myForm, setMyForm] = useState({});

  const handleInput = (e) => {
    const value = e.target.value;
    const name = e.target.name;
    setMyForm((prev) => ({
      ...prev,
      [name]: value,
    }));
  };

  const form1schema = yup.object({
    company_name: yup.string().required(),
  });

  function Step1Form() {
    return (
      <Formik validationSchema={form1schema}>
        {({
          touched,
          isValid,
          isInvalid,
          errors,
          handleBlur,
          handleChange,
          values,
          validateForm,
        }) => (
          <Form noValidate className="formstep1">
            <Form.Group controlId="addCompany">
              <Form.Label>Company Name*</Form.Label>
              <Form.Control
                name="company_name"
                type="text"
                value={myForm.company_name}
                onChange={(e) => {
                  handleChange(e);
                  handleInput(e);
                }}
                isInvalid={!!errors.company_name}
              />
              <Form.Control.Feedback type="invalid">
                {errors.company_name}
              </Form.Control.Feedback>
            </Form.Group>

            <div className="step-progress-btn">
              <Button variant="primary" onClick={() => validateForm()}>
                Validate
              </Button>
            </div>
          </Form>
        )}
      </Formik>
    );
  }

  return <div>Step1Form()</div>;
}
于 2020-10-12T16:58:28.110 回答
0

您的自定义onChange={handleInput}函数永远不会将值传递给 Formik。

Formik 在内部跟踪您的表单值,因此您不需要useState像现在这样使用方法添加它 ( const [myForm, setMyForm] = useState({});)。

当您onChange向表单添加自定义时,您会更改组件状态,而 Formik 的状态永远不会更新,因此 Yup 没有要验证的值。

如果你在你的结束标签下面添加这个</Form>,你会看到 Formik 从不读取你的表单的更新值:

<pre>
  {JSON.stringify(
    {
      touched,
      isValid,
      isInvalid,
      errors,
      handleBlur,
      handleChange,
      values,
      validateForm
    },
    null,
    2
  )}
</pre>
于 2020-10-12T16:39:57.743 回答