Reputation: 120
I am trying to take a class component that allows the user to complete a ReCaptcha and I am trying to rewrite it as a functional component. I am having a bit of trouble so if you guys could tell me what mistake I am making I would greatly appreciate it! If you need to view the node package I am using for the recaptcha here is a link: https://www.npmjs.com/package/react-recaptcha-google. My assumption is that I have somehow made an error with my useRef() hook, but I honestly am unsure.
I am experiencing a few differences in the outcome of my version and the previous.
The first difference is that when the page loads my function verifyCallback(recaptchaToken)
runs immediately, and so the console prints "TOKEN: undefined" whereas in the original nothing is printed (and I assume not run either)
The second difference is when the user completes the recaptcha my function verifyCallback(recaptchaToken)
is NOT called to my knowledge, and so my token is not printed to console, whereas in the original it does print to the console.
Here is the original class component. After the user completes the ReCaptcha and the checkmark appears the variable "recaptchaToken" is printed to the console.
import React from 'react'
import { ReCaptcha } from 'react-recaptcha-google'
class Recaptcha extends React.Component {
constructor(props, context) {
super(props, context);
this.onLoadRecaptcha = this.onLoadRecaptcha.bind(this);
this.verifyCallback = this.verifyCallback.bind(this);
}
componentDidMount() {
if (this.captchaDemo) {
console.log("started, just a second...")
this.captchaDemo.reset();
}
}
onLoadRecaptcha() {
if (this.captchaDemo) {
this.captchaDemo.reset();
}
}
verifyCallback(recaptchaToken) {
console.log("TOKEN:", recaptchaToken);
}
render() {
return (
<div>
<ReCaptcha
ref={(el) => {this.captchaDemo = el;}}
size="normal"
data-theme="dark"
render="explicit"
sitekey=[site_key]
onloadCallback={this.onLoadRecaptcha}
verifyCallback={this.verifyCallback}
/>
<span id="recaptcha-error" className="signup-error"></span>
</div>
);
};
}
export default Recaptcha;
Here is my rewritten code:
import React, {useEffect, useRef} from 'react'
import { ReCaptcha } from 'react-recaptcha-google'
export default function NewRecaptcha() {
const captchaDemo = useRef();
useEffect(() => {
if(captchaDemo.current) {
console.log("started, just a second...")
captchaDemo.current.reset();
}
}, [captchaDemo])
function onLoadRecaptcha() {
if(captchaDemo.current) {
captchaDemo.current.reset();
}
}
function verifyCallback(recaptchaToken) {
console.log("TOKEN:", recaptchaToken);
}
return (
<div>
<ReCaptcha
ref={captchaDemo}
size="normal"
data-theme="dark"
render="explicit"
sitekey=[site_key]
onloadCallback={onLoadRecaptcha()}
verifyCallback={verifyCallback()}
/>
<span id="recaptcha-error" className="signup-error"></span>
</div>
)
}
Upvotes: 0
Views: 38
Reputation: 66
The first difference is that when the page loads my function verifyCallback(recaptchaToken) runs immediately, and so the console prints "TOKEN: undefined" whereas in the original nothing is printed (and I assume not run either)
This is because you are passing verifyCallback()
to the ReCaptcha instead of verifyCallback
so the function is being called and the result is being passed in on the first render. You can fix this by just passing verifyCallback
like this:
<ReCaptcha
// other props
onloadCallback={onLoadRecaptcha}
verifyCallback={verifyCallback}
/>
The second difference is when the user completes the recaptcha my function verifyCallback(recaptchaToken) is NOT called to my knowledge, and so my token is not printed to console, whereas in the original it does print to the console.
This is basically for the same reasons. You should be passing the function itself down to the ReCaptcha component, rather than calling the function and passing that result down.
Upvotes: 1