React Script is a simple way to dynamically load external scripts on both the client and server side for both convenience and performance. This library provides two components, Script
and ScriptProvider
.
It's simple to get a script loading, but you can easily dig into more advanced functionality if you need it.
import React, { Component } from 'react';
import Script from 'react-script';
class Mapbox extends Component {
handleLoad = () => {
// Mapbox is ready!
};
render() {
return (
<Script
url="https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js"
onLoad={this.handleLoad}
/>
)
}
}
React Script also has callbacks for onError
and onCreate
. onCreate
fires when the script is initially injected, so if another component injected the script or it was previously loaded, this callback won't fire.
React Script exclusively works with React 16+ because it relies on the new Context API in React 16.
Yarn:
yarn add react-script
npm:
npm install --save react-script
ScriptProvider takes an injectScript
function, and calls it with whatever scripts are rendered in your app. The parameter passed to that function takes this form:
{
onLoad?: string,
onCreate?: string,
onError?: string,
url: string,
}
The callback functions are strings here because they're functions that you optionally pass to be fired independent of React. When server rendering, you can use this to initialize things without waiting for React.
For example, we use it to start initializing a Mapbox map as soon as we possibly can because it takes a lot of time to boot up. Here's how you can do that:
In your app:
import React, { Component, Fragment } from 'react';
import Script from 'react-script';
class Mapbox extends Component {
componentDidMount() {
// window.mapboxInstance is already ready!
}
handleLoad = () => {
// This fires on the initial Script render because mapbox-gl-js is already loaded
};
render() {
return (
<Fragment>
<Script
url="https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js"
onLoad={{
react: this.handleLoad,
preReact: 'window.mapboxInstance = window.mapboxgl({ container: "mapbox-gl" })',
}}
/>
<div id="mapbox-gl" />
</Fragment>
)
}
}
Where you're handling server rendering:
import React from 'react';
import { ScriptProvider } from 'react-script';
const scripts = [];
const markup = React.renderToString(
<ScriptProvider injectScript={(script) => scripts.push(script)}>
...
</ScriptProvider>
);
res.send(`
<html>
<head />
<body>
${scripts.map(script => (`
<script src="${script.url}" onload="${script.onLoad}" type="text/javascript" />
`))}
</body>
</html>
`)
We have no contibution guide, it's just anarchy live your life
MIT