Skip to content

Commit de916fa

Browse files
committed
use 1.0.0 react-async-script, update readme, update tests
1 parent b6bfe36 commit de916fa

File tree

7 files changed

+70
-87
lines changed

7 files changed

+70
-87
lines changed

README.md

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,13 @@ All you need to do is [sign up for an API key pair][signup]. You will need the c
1717
You can then use the reCAPTCHA. The default require imports a wrapped component that loads the reCAPTCHA script asynchronously.
1818

1919
```jsx
20-
var React = require("react").default;
21-
var render = require("react-dom").render
22-
var ReCAPTCHA = require("react-google-recaptcha");
20+
import ReCAPTCHA from "react-google-recaptcha";
2321

2422
function onChange(value) {
2523
console.log("Captcha value:", value);
2624
}
2725

28-
render(
26+
ReactDOM.render(
2927
<ReCAPTCHA
3028
ref="recaptcha"
3129
sitekey="Your client site key"
@@ -68,7 +66,7 @@ window.recaptchaOptions = {
6866

6967
## Component API
7068

71-
The component also has some utility functions that can be called.
69+
The component instance also has some utility functions that can be called. These can be accessed via `ref`.
7270

7371
- `getValue()` returns the value of the captcha field
7472
- `getWidgetId()` returns the recaptcha widget Id
@@ -85,23 +83,16 @@ Starting with 0.7.0, the component now supports invisible options. See the [reCA
8583
With the invisible option, you need to handle things a bit differently. You will need to call the `execute` method yourself.
8684

8785
```jsx
88-
var React = require("react").default;
89-
var render = require("react-dom").render
90-
var ReCAPTCHA = require("react-google-recaptcha");
91-
92-
function onChange(value) {
93-
console.log("Captcha value:", value);
94-
}
86+
import ReCAPTCHA from "react-google-recaptcha";
9587

9688
let captcha;
9789

98-
render(
90+
ReactDOM.render(
9991
<form onSubmit={() => { captcha.execute(); }}>
10092
<ReCAPTCHA
10193
ref={(el) => { captcha = el; }}
10294
size="invisible"
10395
sitekey="Your client site key"
104-
onChange={onChange}
10596
/>
10697
</form>,
10798
document.body
@@ -114,21 +105,14 @@ render(
114105
You can also use the barebone components doing the following. Using that component will oblige you to manage the grecaptcha dep and load the script by yourself.
115106

116107
```jsx
117-
var React = require("react").default;
118-
var render = require("react-dom").render
119-
var ReCAPTCHA = require("react-google-recaptcha/lib/recaptcha");
108+
import { ReCAPTCHA } from "react-google-recaptcha";
120109

121-
var grecaptchaObject = grecaptcha // You must provide access to the google grecaptcha object.
122-
123-
function onChange(value) {
124-
console.log("Captcha value:", value);
125-
}
110+
const grecaptchaObject = window.grecaptcha // You must provide access to the google grecaptcha object.
126111

127112
render(
128113
<ReCAPTCHA
129-
ref="recaptcha"
114+
ref={(r) => this.recaptcha = r}
130115
sitekey="Your client site key"
131-
onChange={onChange}
132116
grecaptcha={grecaptchaObject}
133117
/>,
134118
document.body
@@ -137,17 +121,7 @@ render(
137121

138122
## Notes
139123

140-
### React < 15.5
141-
With version prior to 15.5
142-
```shell
143-
npm install --save [email protected]
144-
```
145-
146-
### React 0.13
147-
With 0.13, install version 0.4.1
148-
```shell
149-
npm install --save [email protected]
150-
```
124+
Pre `1.0.0` and `React < 15.5.*` support details in [0.14.0](https://github.com/dozoisch/react-google-recaptcha/tree/v0.14.0).
151125

152126
[travis.img]: https://travis-ci.org/dozoisch/react-google-recaptcha.svg?branch=master
153127
[travis.url]: https://travis-ci.org/dozoisch/react-google-recaptcha

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"name": "react-google-recaptcha",
33
"version": "0.14.0",
44
"description": "React Component Wrapper for Google reCAPTCHA",
5-
"main": "lib/recaptcha-wrapper.js",
6-
"module": "lib/es/recaptcha-wrapper.js",
5+
"main": "lib/index.js",
6+
"module": "lib/es/index.js",
77
"directories": {
88
"lib": "lib/"
99
},
@@ -37,7 +37,7 @@
3737
},
3838
"homepage": "https://github.com/dozoisch/react-google-recaptcha",
3939
"peerDependencies": {
40-
"react": ">=15.5.0"
40+
"react": ">=16.4.1"
4141
},
4242
"devDependencies": {
4343
"babel-cli": "^6.0.0",
@@ -67,13 +67,13 @@
6767
"mocha": "~2.3.3",
6868
"mt-changelog": "^0.6.2",
6969
"phantomjs": "^1.9.18",
70-
"react": "^15.5.0",
71-
"react-dom": "^15.5.0",
70+
"react": "^16.4.2",
71+
"react-dom": "^16.4.2",
7272
"release-script": "^0.5.3",
7373
"webpack": "~1.14.0"
7474
},
7575
"dependencies": {
76-
"prop-types": ">=15.5.0",
77-
"react-async-script": ">=0.11.0"
76+
"prop-types": "^15.5.0",
77+
"react-async-script": "1.0.0-rc.1"
7878
}
7979
}

src/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import RecaptchaWrapper from './recaptcha-wrapper';
2+
import ReCAPTCHA from "./recaptcha";
3+
4+
export default RecaptchaWrapper;
5+
export { ReCAPTCHA };

src/recaptcha-wrapper.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ const callbackName = "onloadcallback";
1717
const globalName = "grecaptcha";
1818
const initialOptions = getOptions();
1919

20-
export default makeAsyncScriptLoader(ReCAPTCHA, getURL, {
20+
export default makeAsyncScriptLoader(getURL, {
2121
callbackName,
2222
globalName,
2323
removeOnMount: initialOptions.removeOnMount || false,
24-
exposeFuncs: ["getValue", "getWidgetId", "reset", "execute"],
25-
});
24+
})(ReCAPTCHA);

src/recaptcha.js

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,37 @@ import PropTypes from "prop-types";
44
export default class ReCAPTCHA extends React.Component {
55
constructor() {
66
super();
7-
this.state = {};
87
this.handleExpired = this.handleExpired.bind(this);
98
this.handleRecaptchaRef = this.handleRecaptchaRef.bind(this);
109
}
1110

1211
getValue() {
13-
if (this.props.grecaptcha && this.state.widgetId !== undefined) {
14-
return this.props.grecaptcha.getResponse(this.state.widgetId);
12+
if (this.props.grecaptcha && this._widgetId !== undefined) {
13+
return this.props.grecaptcha.getResponse(this._widgetId);
1514
}
1615
return null;
1716
}
1817

1918
getWidgetId() {
20-
if (this.props.grecaptcha && this.state.widgetId !== undefined) {
21-
return this.state.widgetId;
19+
if (this.props.grecaptcha && this._widgetId !== undefined) {
20+
return this._widgetId;
2221
}
2322
return null;
2423
}
2524

2625
execute() {
2726
const { grecaptcha } = this.props;
28-
const { widgetId } = this.state;
2927

30-
if (grecaptcha && widgetId !== undefined) {
31-
return grecaptcha.execute(widgetId);
28+
if (grecaptcha && this._widgetId !== undefined) {
29+
return grecaptcha.execute(this._widgetId);
3230
} else {
3331
this._executeRequested = true;
3432
}
3533
}
3634

3735
reset() {
38-
if (this.props.grecaptcha && this.state.widgetId !== undefined) {
39-
this.props.grecaptcha.reset(this.state.widgetId);
36+
if (this.props.grecaptcha && this._widgetId !== undefined) {
37+
this.props.grecaptcha.reset(this._widgetId);
4038
}
4139
}
4240

@@ -48,10 +46,10 @@ export default class ReCAPTCHA extends React.Component {
4846
}
4947
}
5048

51-
explicitRender(cb) {
52-
if (this.props.grecaptcha && this.props.grecaptcha.render && this.state.widgetId === undefined) {
49+
explicitRender() {
50+
if (this.props.grecaptcha && this.props.grecaptcha.render && this._widgetId === undefined) {
5351
const wrapper = document.createElement("div");
54-
const id = this.props.grecaptcha.render(wrapper, {
52+
this._widgetId = this.props.grecaptcha.render(wrapper, {
5553
sitekey: this.props.sitekey,
5654
callback: this.props.onChange,
5755
theme: this.props.theme,
@@ -63,12 +61,8 @@ export default class ReCAPTCHA extends React.Component {
6361
badge: this.props.badge,
6462
});
6563
this.captcha.appendChild(wrapper);
66-
67-
this.setState({
68-
widgetId: id,
69-
}, cb);
7064
}
71-
if (this._executeRequested && this.props.grecaptcha && this.state.widgetId !== undefined) {
65+
if (this._executeRequested && this.props.grecaptcha && this._widgetId !== undefined) {
7266
this._executeRequested = false;
7367
this.execute();
7468
}
@@ -83,7 +77,7 @@ export default class ReCAPTCHA extends React.Component {
8377
}
8478

8579
componentWillUnmount() {
86-
if (this.state.widgetId !== undefined) {
80+
if (this._widgetId !== undefined) {
8781
while (this.captcha.firstChild) {
8882
this.captcha.removeChild(this.captcha.firstChild);
8983
}

test/recaptcha-spec.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,46 @@ describe("ReCAPTCHA", () => {
3737
});
3838
it("reset, should call grecaptcha.reset with the widget id", (done) => {
3939
const grecaptchaMock = {
40-
render () {
41-
return "someWidgetId";
42-
},
43-
40+
render () { return "someWidgetId"; },
4441
reset (widgetId) {
4542
assert.isNotNull(widgetId);
4643
done();
4744
},
4845
};
49-
const instance = ReactTestUtils.renderIntoDocument(
50-
<ReCAPTCHA sitekey="xxx" grecaptcha={grecaptchaMock} />,
51-
);
52-
instance.reset();
46+
const ReCaptchaRef = React.createRef();
47+
ReactTestUtils.renderIntoDocument(
48+
(<ReCAPTCHA sitekey="xxx" grecaptcha={grecaptchaMock} ref={ReCaptchaRef} />)
49+
);
50+
ReCaptchaRef.current.reset();
5351
});
5452
it("execute, should call grecaptcha.execute with the widget id", (done) => {
5553
const grecaptchaMock = {
56-
render () {
57-
return "someWidgetId";
58-
},
59-
54+
render () { return "someWidgetId"; },
6055
execute (widgetId) {
6156
assert.isNotNull(widgetId);
6257
done();
6358
},
6459
};
60+
// wrapping component example that applies a ref to ReCAPTCHA
61+
class WrappingComponent extends React.Component {
62+
constructor(props) {
63+
super(props);
64+
this._internalRef = React.createRef();
65+
}
66+
render() { return (
67+
<div>
68+
<ReCAPTCHA
69+
sitekey="xxx"
70+
size="invisible"
71+
grecaptcha={grecaptchaMock}
72+
ref={this._internalRef} />
73+
</div>);
74+
}
75+
}
6576
const instance = ReactTestUtils.renderIntoDocument(
66-
<ReCAPTCHA sitekey="xxx" size="invisible" grecaptcha={grecaptchaMock} />,
67-
);
68-
instance.execute();
77+
(<WrappingComponent />)
78+
);
79+
instance._internalRef.current.execute();
6980
});
7081
describe("Expired", () => {
7182
it("should call onChange with null when response is expired");

test/recaptcha-wrapper-spec.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22
import ReactTestUtils from "react-dom/test-utils";
3-
import ReCAPTCHA from "../src/recaptcha-wrapper"; // eslint-disable-line no-unused-vars
3+
import ReCAPTCHA from "../src/recaptcha-wrapper";
44

55
const VALUE = "some value";
66
const WIDGET_ID = "someWidgetId";
@@ -21,17 +21,17 @@ describe("ReCAPTCHAWrapper", () => {
2121
beforeEach(() => {
2222
window.grecaptcha = grecaptchaMock;
2323
});
24+
afterEach(() => {
25+
delete window.grecaptcha;
26+
});
2427
it("should be wrapped properly", () => {
2528
assert.equal(ReCAPTCHA.displayName, "AsyncScriptLoader(ReCAPTCHA)");
2629
});
2730
it("should proxy functions", () => {
28-
const instance = ReactTestUtils.renderIntoDocument(
29-
<ReCAPTCHA sitekey="xxx" />,
31+
const ReCaptchaRef = React.createRef();
32+
ReactTestUtils.renderIntoDocument(
33+
<ReCAPTCHA sitekey="xxx" ref={ReCaptchaRef} />,
3034
);
31-
assert.ok(instance);
32-
assert.equal(instance.getValue(), VALUE);
33-
});
34-
afterEach(() => {
35-
delete window.grecaptcha;
35+
assert.equal(ReCaptchaRef.current.getValue(), VALUE);
3636
});
3737
});

0 commit comments

Comments
 (0)