@lan9/react-async-script

1.0.0 • Public • Published

React Async Script Loader

Build Status npm version npm downloads Dependencies

*NOTE - These are the docs for the upcoming 1.0.0 release - for v0.11.1 documention go to tag here: 0.11.1

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):
    • 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.

HOC Component props

const AsyncScriptComponent = makeAsyncScriptLoader(URL)(Component);
// ---
<AsyncScriptComponent asyncScriptOnLoad={callAfterScriptLoads} />
  • 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:

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 (<AsyncHoc ref={this._internalRef} />)}
}
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

// 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 (
    <div ref={(r) => 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(
  <ReCAPTCHAWrapper asyncScriptOnLoad={onLoad} />,
  document.body
);

Migration to 1.0

  • Component is now passed as a second function call
  • removeOnMount is now removeOnUnmount (typo fixed!)
  • exposeFuncs is no longer needed as it's done automatically!
-export default makeAsyncScriptLoader(ReCAPTCHA, getURL, {
+export default makeAsyncScriptLoader(getURL, {
   callbackName,
   globalName,
-  removeOnMount: initialOptions.removeOnMount || false,
+  removeOnUnmount: initialOptions.removeOnUnmount || false,
-  exposeFuncs: ["getValue", "getWidgetId", "reset", "execute"],
-});
+})(ReCAPTCHA);

Notes

Pre 1.0.0 and - React < React@16.4.1 support details in 0.11.1.


Package Sidebar

Install

npm i @lan9/react-async-script

Weekly Downloads

3

Version

1.0.0

License

MIT

Unpacked Size

37.8 kB

Total Files

10

Last publish

Collaborators

  • lan9