disable form submit button until user checks recaptcha checkbox

Viewed 2188

I'm trying to disable my form's submit button until the user clicks the Google Recaptcha checkbox 'I am not a robot'

Is there anyway to do this or do I need to download a React component specific to Google Recaptcha?

Here is my simple component that contains the Google Recaptcha:

const RecaptchaComponent = () => {
    useEffect(() => {
        // Add reCaptcha
        const script = document.createElement("script");
        script.src = "https://www.google.com/recaptcha/api.js"
        document.body.appendChild(script);
    }, [])

    return (
        <div
            className="g-recaptcha"
            data-sitekey="6LeS8_IdfdfLtQzwUgNV4545454lhvglswww14U"
        ></div>
    )
};

And here is my form's onSubmit code:

const GameForm = () => (

<div className="app">

    <Formik
        initialValues={{
            email: "",
            name: "",
            title: ""

        }}

        onSubmit={(values) => {
            //new Promise(resolve => setTimeout(resolve, 500));
            axios({
                method: "POST",
                url: "api/gameform",
                data: JSON.stringify(values),
            });
        }}
    >

        {props => {
            const {
                values,
                isSubmitting,
                handleSubmit,

            } = props;

            return (
                <form onSubmit={handleSubmit}>

                    <div>Your Game</div>

                    <label htmlFor="title">
                        Game Title:
                    </label>
                    <Field
                        id="title"
                        type="text"
                        values={values.title}
                    />

                    <label htmlFor="name">
                        Name:
                    </label>
                    <Field
                        id="name"
                        type="text"
                        value={values.name}
                    />

                    <label htmlFor="email">
                        Email:
                    </label>
                    <Field
                        id="email"
                        name="email"
                        type="email"
                        value={values.email}
                    />

                    <div>
                    <ReCAPTCHA 
                        sitekey="6LeS8_IUAAAAAhteegfgwwewqe223" 
                        onChange={useCallback(() => setDisableSubmit(false))}
 />
                    </div>
                    <div>
                        <Button type="submit">
                            Submit
                        </Button>
                    </div>
                </form>
            );
        }}
    </Formik>

</div>
);
1 Answers

You don't need to use the react component, but it's easier.

export const MyForm = () => {

   const [disableSubmit,setDisableSubmit] = useState(true);

   return (
     ... rest of your form
     <ReCAPTCHA 
         sitekey="6LeS8_IdfdfLtQzwUgNV4545454lhvglswww14U" 
         onChange={useCallback(() => setDisableSubmit(false))}
     />
     <button type="submit" disabled={disableSubmit}>Submit</button>
   )

}

EDIT:

One of my biggest pet peeves is seeing React tutorials where authors encourage devs to use functions that return JSX instead of just using functional components.

Formik's "children as a function" pattern is gross (react-router-dom does the same thing) - it should be a component:

const GameForm = () => {
  return <Formik ...your props>{props => <YourForm {...props}/>}</Formik>
}

const YourForm = (props) => {
   const [disableSubmit,setDisableSubmit] = useState(true);


   ... everything inside the child function in `GameForm`
}
Related