如何在 Formik 中使用一个验证模式字段验证多封电子邮件?

How to validate multiple emails using one validation schema field in Formik?

我有一个包含两个值的客户表单。

  1. 客户名称
  2. 客户邮箱(可以是多个)

我在电子邮件字段旁边提供了一个添加按钮,用户可以通过该按钮向表单添加更多电子邮件。现在我想验证已添加的每封电子邮件。如果它被添加,它也是必需的。不允许使用空电子邮件。

问题是我只有一个验证模式来验证电子邮件字段。我如何使用同一个字段来验证多个电子邮件?

即使添加了正确的电子邮件。它仍然给出错误!

请查看沙箱 link 以查看代码。 code sandbox link

这是包含多个电子邮件验证和错误的工作代码。
我使用 Formik FieldArray 来处理多封电子邮件。
您可以在您的沙箱中用这个替换您的代码进行测试。

import React from "react";
import { TextField, IconButton } from "@material-ui/core";
import {
  AddCircleOutlined as AddCircleOutlinedIcon,
  IndeterminateCheckBox as IndeterminateCheckBoxIcon
} from "@material-ui/icons";

//FORMIK
import { Formik, FieldArray, getIn, ErrorMessage } from "formik";
import * as Yup from "yup";

export default function UnitsDrawer(props) {
  const callAPI = e => {
    console.log(e.name);
    console.log(e.email);
  };

  const testSchema = Yup.object().shape({
    name: Yup.string().required("Customer name is required"),
    email: Yup.array().of(
      Yup.string()
        .email("Enter a valid email")
        .required("Email is required")
    )
  });

  const initialValues = {
    name: "",
    email: [""]
  };

  const formRef = React.useRef();

  return (
    <div>
      <Formik
        innerRef={formRef}
        validationSchema={testSchema}
        initialValues={initialValues}
        onSubmit={(values, actions) => {
          actions.setSubmitting(false);
          callAPI(values);
        }}
      >
        {({
          handleChange,
          handleBlur,
          values,
          errors,
          touched,
          handleSubmit,
          isSubmitting,
        }) => {
          return (
            <>
              <div>
                <TextField
                  label="Customer Name"
                  name="name"
                  margin="normal"
                  variant="outlined"
                  error={errors.name && touched.name}
                  onChange={handleChange}
                  onBlur={handleBlur}
                  value={values.name}
                  fullWidth
                />
                <ErrorMessage name="name" component="div" />
              </div>
              <FieldArray name="email">
                {({ push, remove }) =>
                  values.email.map((field, index) => (
                    <div key={`${index}`} className="dynamic-fields">
                      <div>
                        <TextField
                          label="Email"
                          variant="outlined"
                          className="input-item"
                          error={
                            getIn(touched, `email.${index}`) &&
                            getIn(errors, `email.${index}`)
                          }
                          name={`email.${index}`}
                          value={values.email[index]}
                          onChange={handleChange}
                          onBlur={handleBlur}
                          fullWidth
                        />
                        <ErrorMessage name={`email.${index}`} component="div" />
                      </div>
                      <IconButton
                        aria-label="filter list"
                        className="add-icon"
                        onClick={() => {
                          push("");
                        }}
                      >
                        <AddCircleOutlinedIcon color="primary" />
                      </IconButton>
                      {values.email.length > 1 && (
                        <IconButton
                          aria-label="filter list"
                          className="add-icon"
                          onClick={() => {
                            remove(index);
                          }}
                        >
                          <IndeterminateCheckBoxIcon />
                        </IconButton>
                      )}
                    </div>
                  ))
                }
              </FieldArray>
            </>
          );
        }}
      </Formik>
    </div>
  );
}