Formik验证中,isSubmitting/isValidating没有被设置为true。

4

我的用户要求我让表单无效化更加明显。因此,我计划弹出一个 sweetalert 对话框,让他们知道需要仔细检查表单。我认为可以在验证中这样做,以在提交尝试失败时警告他们:

const validate = values => {
    console.log(formik.isSubmitting); // always prints false
    console.log(formik.isValidating); // always prints false
    const errors = {};
    if (!values.name) {
      errors.name = 'Required';
    }

    if (Object.keys(errors).length > 0 && formik.isSubmitting) {
        Swal.fire({
            icon: 'error',
            title: "Oops. . .",
            text: "There are errors with the form. Please double check your options.",
            footer: "<div>Problems: " + Object.keys(errors).join(', ') + "</div>"
        })
    }

    return errors;
};

const formik = useFormik({
    initialValues: {
        name: item.name
    },
    enableReinitialize: true,
    validate,
    onSubmit: values => {
       // also tried adding 
       formik.setSubmitting(true); 
       //do stuff
    }
})

但是isSubmitting / isValidating始终为false。我是否需要传递其他属性到validate函数中以便访问这些值? https://codesandbox.io/s/nervous-wescoff-cf2y1?file=/src/App.js

如果您能在代码沙盒或类似工具中重现该问题,我保证我们能够解决它。 - Raicuparta
1个回答

2
我认为在 validate 方法中展示对话框并不是一个好的做法,你的使用场景看起来像是一个自定义需求,formik 库在表单提交时内部分享了他们的做法-https://formik.org/docs/guides/form-submission
你可以添加一个自定义方法进行提交。
所以,我已经 fork 了你的 sandbox 并进行了更新-https://codesandbox.io/s/custom-form-submit-stackoverflow-8znzf
让我知道你的想法。
编辑:添加代码,即使链接过期,你仍然可以知道该如何操作。
import React, { useState } from "react";
import "./styles.css";
import { useFormik } from "formik";
import Swal from "sweetalert2";
import "bootstrap/dist/css/bootstrap.min.css";

export default function App() {
  const [item, setItem] = useState({
    name: "",
    email: ""
  });

  const validate = (values) => {
    console.log("values: ", values);
    const errors = {};
    if (!values.name) {
      errors.name = "Required";
    }
    return errors;
  };

  const initialValues = {
    name: item.name,
    email: item.email
  };

  const formik = useFormik({
    initialValues,
    enableReinitialize: true,
    validate,
    onSubmit: (values) => {
      console.log("inside onSubmit", values);
    }
  });

  const customSubmitHandler = (event) => {
    event.preventDefault();
    const touched = Object.keys(initialValues).reduce((result, item) => {
      result[item] = true;
      return result;
    }, {});
    // Touch all fields without running validations
    formik.setTouched(touched, false);
    formik.setSubmitting(true);

    formik
      .validateForm()
      .then((formErrors) => {
        if (Object.keys(formErrors).length > 0) {
          Swal.fire({
            icon: "success",
            title: "Yes. . .",
            text: "This one should fire if everything is working right",
            footer:
              "<div>Problems: " + Object.keys(formErrors).join(", ") + "</div>"
          });
        } else {
          formik.handleSubmit(event);
        }
        formik.setSubmitting(false);
      })
      .catch((err) => {
        formik.setSubmitting(false);
      });
  };

  return (
    <form id="campaignForm" onSubmit={customSubmitHandler}>
      <div className="form-group">
        <label htmlFor="name">Name</label>
        <input
          id="name"
          type="text"
          onChange={formik.handleChange}
          value={formik.values.name}
          className="form-control"
          placeholder="Enter name"
        />
        {formik.errors.name ? (
          <div className="text-danger">{formik.errors.name}</div>
        ) : null}
      </div>
      <div className="form-group">
        <label htmlFor="name">Email</label>
        <input
          id="name"
          type="email"
          onChange={formik.handleChange}
          value={formik.values.email}
          className="form-control"
          placeholder="Enter email"
        />
        {formik.errors.email ? (
          <div className="text-danger">{formik.errors.email}</div>
        ) : null}
      </div>
      <div className="form-group">
        <button className="btn btn-info" type="submit">
          Submit
        </button>
      </div>
    </form>
  );
}

为了增加更多的上下文:我遵循了formik在表单提交方面的内部操作,除了我在触发formik的onSubmit方法之前添加了自定义逻辑(以显示对话框)。当使用formik时,您会注意到当表单没有错误时,onSubmit中的逻辑按预期运行。 - ypahalajani
同意...从“单一职责原则”的角度来看...验证器进行验证。由类的使用者来“响应”。 - Prisoner ZERO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接