Skip to content

Instantly share code, notes, and snippets.

@nickdandakis
Created June 2, 2019 21:09
Show Gist options
  • Save nickdandakis/87159d4eb9dd7a95035d54050b6d1550 to your computer and use it in GitHub Desktop.
Save nickdandakis/87159d4eb9dd7a95035d54050b6d1550 to your computer and use it in GitHub Desktop.
A React component for Google's ReCAPTCHA
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class ReCAPTCHA extends Component {
static propTypes = {
sitekey: PropTypes.string.isRequired,
onVerify: PropTypes.func,
};
static defaultProps = {
onVerify: () => {},
};
static isReady() {
return typeof window !== 'undefined' && typeof window.grecaptcha !== 'undefined';
}
componentDidMount() {
if (ReCAPTCHA.isReady()) {
this.renderOnReady();
} else {
this.renderOnReadyInterval = setInterval(this.renderOnReady, 500);
}
}
componentWillUnnmount() {
if (this.renderOnReadyInterval) {
clearInterval(this.renderOnReadyInterval);
}
}
renderOnReady = () => {
if (ReCAPTCHA.isReady() && !this.renderedEl) {
this.renderReCAPTCHA();
} else if (ReCAPTCHA.isReady()) {
clearInterval(this.renderOnReadyInterval);
}
}
renderReCAPTCHA() {
const { sitekey, onVerify } = this.props;
try {
this.renderedEl = window.grecaptcha.render(this.$el, {
sitekey,
callback: onVerify,
});
} catch (error) {
if (error.message !== 'reCAPTCHA has already been rendered in this element') {
throw error;
}
// no-op if ReCAPTCHA already rendered (server-side render bug)
}
}
render() {
const { sitekey } = this.props;
return (
<div
className="g-recaptcha"
data-sitekey={sitekey}
ref={(el) => { this.$el = el; }}
/>
);
}
}
export default ReCAPTCHA;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment