appleboy / react-recaptcha

A react.js reCAPTCHA for Google
https://www.google.com/recaptcha/intro/index.html
BSD 3-Clause "New" or "Revised" License
634 stars 97 forks source link

.verifyCallback() does not work with es6 classes #231

Open reZach opened 6 years ago

reZach commented 6 years ago

Hello,

When calling the .execute() method on the recaptcha instance, the verifyCallback function is not called if within an es6 class. The verifyCallback is only called when outside the class. This is not ideal as it doesn't allow you to submit a form.

Doesn't work

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
var Recaptcha = require('react-recaptcha');

export class Submit extends React.Component<RouteComponentProps<{}>, {}>{
    recaptchaInstance: any;
    constructor() {
        super();

        this.executeCaptcha = this.executeCaptcha.bind(this);
        this.verifyCallback = this.verifyCallback.bind(this);
    }

    executeCaptcha() {
        this.recaptchaInstance.execute();
    }

    verifyCallback(response){
        console.log(response); // never is called
        // submit form
    }

    render() {
        return <div>
            <form onSubmit={this.executeCaptcha}>
                <button>Send</button>
            </form>
            <Recaptcha
                 ref={e => this.recaptchaInstance = e}
                 sitekey="xxxxxxxxxxxxxxxxxxxx"
                 size="invisible"
                 verifyCallback={this.verifyCallback}
            />
        </div>;
    }
}

It does work this way

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
var Recaptcha = require('react-recaptcha');

const verifyCallback = function(response){
    console.log(response);
    // can't submit form now!? (or is there a way)
}

export class Submit extends React.Component<RouteComponentProps<{}>, {}>{
    recaptchaInstance: any;
    constructor() {
        super();

        this.executeCaptcha = this.executeCaptcha.bind(this);
        this.verifyCallback = this.verifyCallback.bind(this);
    }

    executeCaptcha() {
        this.recaptchaInstance.execute();
    }

    verifyCallback(response){
        console.log(response); // never is called
    }

    render() {
        return <div>
            <form onSubmit={this.executeCaptcha}>
                <button>Send</button>
            </form>
            <Recaptcha
                 ref={e => this.recaptchaInstance = e}
                 sitekey="xxxxxxxxxxxxxxxxxxxx"
                 size="invisible"
                 verifyCallback={this.verifyCallback}
            />
        </div>;
    }
}

Is there a way we can stick the verifyCallback in the class?

zhuangya commented 6 years ago

workaround: pass any function to onloadCallback

why: https://github.com/appleboy/react-recaptcha/blob/52a22d896e556357517aa7078c33359346d1ed28/src/index.js#L69

if the component mount BEFORE the grecaptcha arrives, it would not call _renderGrecaptcha if render === 'explicit' && onloadCallback && this.state.ready && !prevState.ready is false.

12345-gh commented 6 years ago

I changed my key using this instruction https://codelabs.developers.google.com/codelabs/reCAPTCHA/index.html#2 and verifyCallback began to work after execute. Perhaps this will help someone.

jstorm31 commented 6 years ago

@zhuangya workaround works, but only for 1 form submit. Even if a function is passed to onloadCallback, repeated form submit does not trigger verifyCallback.

jsardev commented 6 years ago

@zhuangya The workaround doesn't work for me :( verifyCallback still does not execute.

jsardev commented 6 years ago

Hey guys! As I encountered the same issue and couldn't solve it in a clean way I decided to create my own library. It has some improvements comparing to this lib and most important - it works completely fine! 🚀 Verify callback just works and what's awesome - you can have everything in your React component (not outside in some global variables).

Library: https://github.com/sarneeh/reaptcha Example: https://sarneeh.github.io/reaptcha/

Hope it helps! 😄 🎉

thomasjthomasj commented 6 years ago

@sarneeh Had this exact problem and this helped a bunch, and is much nicer to use that the appleboy library! Do you intend to continue to maintain it, for instance, after Google deprecate V2 for V3?

jsardev commented 6 years ago

@thomasjthomasj As the library is very small and the functionality isn't a big deal I think I'll have time to maintain it for a longer period of time :) I'm "active" (not contributing much, but following things that happen) on GitHub, so I think it won't be a problem.

About reCAPTCHA v3 - I've actually thought about implementing it right away, but I've noticed that reCAPTCHA v3 is still in development and there might be major changes. So I've decided to leave it for now and when it will get stable - I will add support for it.