2

我正在尝试使隐形react-google-recaptchaFormikyup一起工作。文档说我们应该调用recaptchaRef.current.execute()表单提交,但是如果我们同时使用 Formik 和 yup,它只会在所有字段都通过验证模式后触发提交逻辑。

基本上,我们需要调用该execute方法,更新recaptcha 值并使用相同的触发事件提交表单。我的问题正是:我必须使用两个事件(一个用于execute方法并更新recaptcha + 一个用于提交表单)。

检查此沙箱:https ://codesandbox.io/s/keen-mahavira-ont8z?file=/src/App.js

如您所见,表单仅在第二次单击提交按钮时提交...

4

1 回答 1

5

使用 Formik,有一些方法可以为您的表单做后台工作。这基本上可以通过将道具传递给表单组件handleChange来实现。handleBlur

例如,我相信您的表单元素中会有其他输入,而不仅仅是验证码 ( if it's just a captcha in the form, then do let me know! - this can also be solved)

所以当你有其他元素时,你可以确保使用Formik的一些API来处理自动触发:

正如我所看到的,有很多方法可以通过他们的 API 来处理这个问题:https ://formik.org/docs/api/formik

我尝试实现它的方法是onBlur在所有字段上添加一个侦听器,然后检查是否存在 reCaptcha 值。基于此,我触发执行验证码并确保将提交值设置为 true:

const handleBlur = (e) => {
  console.log("$$$$", props.isSubmitting);
  if (!props.values.recaptcha) {
    this._reCaptchaRef.current.execute();
    props.setSubmitting(true);
  }
  props.handleBlur(e);
};

这是 CodeSandbox 链接:https ://codesandbox.io/s/silly-saha-qq7hg?file=/src/App.js

这显示了处理onBlur字段并在后台触发它的工作模型。如果您注意到,您还可以使用isSubmitting和禁用和启用提交按钮setSubmitting

还设置validateOnChange={false}and validateOnBlur={false},因为不需要验证验证码的更改或模糊。

在此处粘贴代码以供您浏览:

import React, { Component, createRef } from "react";

import ReCAPTCHA from "react-google-recaptcha";
import { Formik } from "formik";
import * as yup from "yup";

const TEST_SITE_KEY = "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI";

export default class MyForm extends Component {
  constructor(props) {
    super(props);
    this._validationSchema = yup.object().shape({
      recaptcha: yup.string().required(),
      name: yup.string().required(),
      address: yup.string().required()
    });
    this._initialValues = { recaptcha: "", name: "", address: "" };
    this._reCaptchaRef = createRef();
  }

  render() {
    return (
      <Formik
        validationSchema={this._validationSchema}
        initialValues={this._initialValues}
        validateOnChange={false}
        validateOnBlur={false}
        onSubmit={(values) => console.log(values)}
      >
        {(props) => {
          const handleBlur = (e) => {
            console.log("$$$$", props.isSubmitting);
            if (!props.values.recaptcha) {
              this._reCaptchaRef.current.execute();
              props.setSubmitting(true);
            }
            props.handleBlur(e);
          };

          return (
            <form onSubmit={props.handleSubmit}>
              <label>Name: </label>
              <input
                type="text"
                onChange={props.handleChange}
                value={props.values.name}
                name="name"
                onBlur={handleBlur}
              />
              <label>Address: </label>
              <input
                type="text"
                onChange={props.handleChange}
                value={props.values.address}
                name="address"
                onBlur={handleBlur}
              />
              <ReCAPTCHA
                ref={this._reCaptchaRef}
                sitekey={TEST_SITE_KEY}
                onChange={(value) => {
                  console.log("$$$$", props.isSubmitting, value);
                  props.setFieldValue("recaptcha", value);
                  props.setSubmitting(false);
                }}
                size="invisible"
              />
              <button type="submit" disabled={props.isSubmitting}>
                SUBMIT
              </button>

              {props.errors.name && <div>{props.errors.name}</div>}
            </form>
          );
        }}
      </Formik>
    );
  }
}
于 2021-02-02T01:41:52.513 回答