簡體   English   中英

如何讓隱形 react-google-recaptcha、Formik 和 yup 協同工作?

[英]How to make invisible react-google-recaptcha, Formik and yup work together?

我正在嘗試讓隱形react-google-recaptchaFormikyup一起工作。 文檔說我們應該在表單提交時調用recaptchaRef.current.execute() ,但是如果我們同時使用 Formik 和 yup ,它只會在所有字段都通過驗證模式后觸發提交邏輯。

基本上,我們需要調用execute方法,更新recaptcha 值並使用相同的觸發事件提交表單。 我的問題正是:我必須使用兩個事件(一個用於execute方法並更新recaptcha + 一個用於提交表單)。

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

如您所見,表單僅在第二次單擊提交按鈕時提交...

使用 Formik,有一些方法可以為您的表單做后台工作。 這基本上可以通過將handleChangehandleBlur道具傳遞給表單組件來實現。

例如,我相信您的表單元素中會有其他輸入,而不僅僅是驗證碼( 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並在后台觸發它的工作 model。 如果您注意到,您還可以使用isSubmittingsetSubmitting禁用和啟用提交按鈕。

還要設置validateOnChange={false}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>
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM