如何让不可见的react-google-recaptcha、Formik和yup协同工作?
How to make invisible react-google-recaptcha, Formik and yup work together?
我正在尝试让隐形 react-google-recaptcha, Formik and yup 一起工作。文档说我们应该在表单提交时调用recaptchaRef.current.execute()
,但是如果我们同时使用Formik和yup,它只会在所有字段都通过验证模式后才会触发提交逻辑。
基本上,我们需要调用 execute
方法,更新 recaptcha 值并使用相同的触发事件提交表单。我的问题正是:我必须使用两个事件(一个用于 execute
方法并更新 recaptcha + 一个用于提交表单)。
检查这个沙箱:https://codesandbox.io/s/keen-mahavira-ont8z?file=/src/App.js
如您所见,仅在第二次单击提交按钮时提交表单...
使用 Formik,有一些方法可以为您的表单做后台工作。这基本上可以通过将 handleChange
或 handleBlur
道具传递给表单组件来实现。
例如,我相信您的表单元素中会有其他输入,而不仅仅是验证码 (if it's just a captcha in the form, then do let me know! - this can also be solved
)
所以当你有其他元素时,你可以确保使用一些Formik的API来处理自动触发:
- handleBlur 事件触发 ReCaptcha
- isSubmitting 控制提交按钮的状态
- setSubmitting 事件来操纵按钮的状态
据我所知,有很多方法可以通过他们的 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 Link:https://codesandbox.io/s/silly-saha-qq7hg?file=/src/App.js
这显示了处理 onBlur
字段并在后台触发它的工作模型。如果您注意到,您还可以使用 isSubmitting
和 setSubmitting
.
禁用和启用提交按钮
同时设置 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>
);
}
}
我正在尝试让隐形 react-google-recaptcha, Formik and yup 一起工作。文档说我们应该在表单提交时调用recaptchaRef.current.execute()
,但是如果我们同时使用Formik和yup,它只会在所有字段都通过验证模式后才会触发提交逻辑。
基本上,我们需要调用 execute
方法,更新 recaptcha 值并使用相同的触发事件提交表单。我的问题正是:我必须使用两个事件(一个用于 execute
方法并更新 recaptcha + 一个用于提交表单)。
检查这个沙箱:https://codesandbox.io/s/keen-mahavira-ont8z?file=/src/App.js
如您所见,仅在第二次单击提交按钮时提交表单...
使用 Formik,有一些方法可以为您的表单做后台工作。这基本上可以通过将 handleChange
或 handleBlur
道具传递给表单组件来实现。
例如,我相信您的表单元素中会有其他输入,而不仅仅是验证码 (if it's just a captcha in the form, then do let me know! - this can also be solved
)
所以当你有其他元素时,你可以确保使用一些Formik的API来处理自动触发:
- handleBlur 事件触发 ReCaptcha
- isSubmitting 控制提交按钮的状态
- setSubmitting 事件来操纵按钮的状态
据我所知,有很多方法可以通过他们的 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 Link:https://codesandbox.io/s/silly-saha-qq7hg?file=/src/App.js
这显示了处理 onBlur
字段并在后台触发它的工作模型。如果您注意到,您还可以使用 isSubmitting
和 setSubmitting
.
同时设置 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>
);
}
}