With Formik, there are some ways to do background work for your form's. This basically could be achieved with handleChange
or handleBlur
props being passed to the form component.
For instance, I am sure you would have other inputs in your form elements and not just a captcha (if it's just a captcha in the form, then do let me know! - this can also be solved
)
So when you have other elements, you can ensure to use some of the Formik's API to handle the automatic trigger:
As I see, there are a lot of ways to handle this through their API's: https://formik.org/docs/api/formik
The way I tried to achieve it is by adding a listener for onBlur
on all fields and then checking if reCaptcha value is present or not. Based on that I trigger the execute the captcha and ensure to set the submitting value as true:
const handleBlur = (e) => {
console.log("$$$$", props.isSubmitting);
if (!props.values.recaptcha) {
this._reCaptchaRef.current.execute();
props.setSubmitting(true);
}
props.handleBlur(e);
};
Here is the CodeSandbox Link: https://codesandbox.io/s/silly-saha-qq7hg?file=/src/App.js
This shows the working model of handling onBlur
of a field and triggering it in the background. If you notice, you can also disable and enable the submit button using isSubmitting
and setSubmitting
.
Also setting validateOnChange={false}
and validateOnBlur={false}
, because there is no need to validate on change or blur for captcha.
Pasting code here just in case for you to glance:
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>
);
}
}