An open API service indexing awesome lists of open source software.

https://github.com/dozoisch/react-async-script

A React composition mixin for loading 3rd party scripts asynchronously
https://github.com/dozoisch/react-async-script

hacktoberfest hacktoberfest2020 javascript reactjs

Last synced: 11 months ago
JSON representation

A React composition mixin for loading 3rd party scripts asynchronously

Awesome Lists containing this project

README

          

# React Async Script Loader

[![Build Status][ci.img]][ci.url] [![npm version][npm.img]][npm.url] [![npm downloads][npm.dl.img]][npm.dl.url]

A React HOC for loading 3rd party scripts asynchronously. This HOC allows you to wrap a component that needs 3rd party resources, like reCAPTCHA or Google Maps, and have them load the script asynchronously.

## Usage

#### Async Script HOC api

`makeAsyncScriptLoader(getScriptUrl, options)(Component)`

- `Component`: The *Component* to wrap.
- `getScriptUrl`: *string* or *function* that returns the full URL of the script tag.
- `options` *(optional)*:
- `attributes`: *object* : If the script needs attributes (such as `data-` attributes), then provide them as key/value pairs of strings and they will be added to the generated script tag.
- `callbackName`: *string* : If the script needs to call a global function when finished loading *(for example: `recaptcha/api.js?onload=callbackName`)*. Please provide the callback name here and it will be autoregistered on `window` for you.
- `globalName`: *string* : Can provide the name of the global that the script attaches to `window`. Async-script will pass this as a prop to the wrapped component. *(`props[globalName] = window[globalName]`)*
- `removeOnUnmount`: *boolean* **default=false** : If set to `true` removes the script tag when component unmounts.
- `scriptId`: *string* : If set, it adds the following id on the script tag.

#### HOC Component props
```js
const AsyncScriptComponent = makeAsyncScriptLoader(URL)(Component);
// ---

```
- `asyncScriptOnLoad`: *function* : called after script finishes loading. *using `script.onload`*

#### Ref and forwardRef

`react-async-script` uses react's `forwardRef` method to pass along the `ref` applied to the wrapped component.

If you pass a `ref` prop you'll have access to your wrapped components instance. See the tests for detailed example.

Simple Example:
```js
const AsyncHoc = makeAsyncScriptLoader(URL)(ComponentNeedsScript);

class DisplayComponent extends React.Component {
constructor(props) {
super(props);
this._internalRef = React.createRef();
}
componentDidMount() {
console.log("ComponentNeedsScript's Instance -", this._internalRef.current);
}
render() { return ()}
}
```

##### Notes on Requirements

At least `React@16.4.1` is required due to `forwardRef` usage internally.

### Example

See https://github.com/dozoisch/react-google-recaptcha

```js
// recaptcha.js
export class ReCAPTCHA extends React.Component {
componentDidUpdate(prevProps) {
// recaptcha has loaded via async script
if (!prevProps.grecaptcha && this.props.grecaptcha) {
this.props.grecaptcha.render(this._container)
}
}
render() { return (

this._container = r} />)
}
}

// recaptcha-wrapper.js
import makeAsyncScriptLoader from "react-async-script";
import { ReCAPTCHA } from "./recaptcha";

const callbackName = "onloadcallback";
const URL = `https://www.google.com/recaptcha/api.js?onload=${callbackName}&render=explicit`;
// the name of the global that recaptcha/api.js sets on window ie: window.grecaptcha
const globalName = "grecaptcha";

export default makeAsyncScriptLoader(URL, {
callbackName: callbackName,
globalName: globalName,
})(ReCAPTCHA);

// main.js
import ReCAPTCHAWrapper from "./recaptcha-wrapper.js"

const onLoad = () => console.log("script loaded")

React.render(
,
document.body
);
```

---

[ci.img]: https://github.com/dozoisch/react-async-script/actions/workflows/standard-ci.yml/badge.svg?branch=master
[ci.url]: https://github.com/dozoisch/react-async-script/actions/workflows/standard-ci.yml
[npm.img]: https://badge.fury.io/js/react-async-script.svg
[npm.url]: http://badge.fury.io/js/react-async-script
[npm.dl.img]: https://img.shields.io/npm/dm/react-async-script.svg
[npm.dl.url]: https://www.npmjs.com/package/react-async-script