How to record external chain js file in react component

1. Description All of the following are from A complete collection of my github articles Content. Welcome to github, sta...
1. Description

All of the following are from A complete collection of my github articles Content. Welcome to github, star, issue welcome!

2. How to add js file in react component
export default class Script extends React.Component { static propTypes = { attributes: RPT.object, // eslint-disable-line react/forbid-prop-types onCreate: RPT.func, onError: RPT.func.isRequired, onLoad: RPT.func.isRequired, url: RPT.string.isRequired, }; static defaultProps = { attributes: {}, onCreate: () => {}, onError: () => {}, onLoad: () => {}, } // A dictionary mapping script URLs to a dictionary mapping // component key to component for all components that are waiting // for the script to load. static scriptObservers = {}; // Whether the specific URL has been loaded // this.constructor.scriptObservers[url][this.scriptLoaderId] = this.props; // Each URL corresponds to multiple scriptloaderids, but only one will be checked to see if it has been loaded static loadedScripts = {}; // this.constructor.loadedScripts[url] = true; static erroredScripts = {}; // this.constructor.erroredScripts[url] = true; static idCount = 0; // How many objects has the component been instantiated constructor(props) { super(props); this.scriptLoaderId = `id${this.constructor.idCount++}`; //1. If a page has more than one Script label, its specific this.scriptLoaderId is unique } componentDidMount() { const { onError, onLoad, url } = this.props; //fix 1: if the URL has already been loaded, and then it is required to be loaded elsewhere on the page, because this.constructor.loadedScripts[url] has been set to true, then directly call the onLoad method if (this.constructor.loadedScripts[url]) { onLoad(); return; } //fix 2: if the URL has been loaded, and there is an error in loading, and then it is required to load elsewhere on the page, because tthis.constructor.erroredScripts[url] has been set to true, then directly call the onError method if (this.constructor.erroredScripts[url]) { onError(); return; } // If the script is loading, add the component to the script's observers // and return. Otherwise, initialize the script's observers with the component // and start loading the script. // fix 3: if a URL is already loaded, that is, this.constructor.scriptservers [url] is set to a specific value, then if the URL is also required, it will be returned directly to prevent a component from being loaded multiple times if (this.constructor.scriptObservers[url]) { this.constructor.scriptObservers[url][this.scriptLoaderId] = this.props; return; } //8. This.constructor.scriptservers is used to register a URL specific object. Its value is all props objects added for the component, and the key is this.scriptLoaderId of the component instance this.constructor.scriptObservers[url] = { [this.scriptLoaderId]: this.props }; this.createScript(); } componentWillUnmount() { const { url } = this.props; const observers = this.constructor.scriptObservers[url]; // If the component is waiting for the script to load, remove the // component from the script's observers before unmounting the component. // componentWillUnmount just uninstalls the current component instance, so delete this.scriptLoaderId of the current instance directly if (observers) { delete observers[this.scriptLoaderId]; } } createScript() { const { onCreate, url, attributes } = this.props; //1.onCreate is called after the script tag is created const script = document.createElement('script'); onCreate(); // add 'data-' or non standard attributes to the script tag // 2. All attributes specified by attributes will be added to the script tag if (attributes) { Object.keys(attributes).forEach(prop => script.setAttribute(prop, attributes[prop])); } script.src = url; // default async to true if not set with custom attributes // 3. If the script tag has no async attribute, it means it is not loaded asynchronously if (!script.hasAttribute('async')) { script.async = 1; } //5.shouldRemoveObserver(observers[key]) is used to remove specific listeners and trigger onLoad const callObserverFuncAndRemoveObserver = (shouldRemoveObserver) => { const observers = this.constructor.scriptObservers[url]; //Listen to the scriptObservers of the current URL, and then obtain the key of the Observer, which corresponds to this.scriptLoaderId. Each component instance is unique. A URL may correspond to multiple this.scriptloaderids: // if (this.constructor.scriptObservers[url]) { // this.constructor.scriptObservers[url][this.scriptLoaderId] = this.props; // return; // } Object.keys(observers).forEach((key) => { //If a specific key corresponds to, the incoming observers[key] is this.props of the component instance if (shouldRemoveObserver(observers[key])) { delete this.constructor.scriptObservers[url][this.scriptLoaderId]; } }); }; //4.onload sets the loaded state of the URL to true script.onload = () => { this.constructor.loadedScripts[url] = true; callObserverFuncAndRemoveObserver((observer) => { //6. Calling the user's own onLoad indicates that the script is loaded observer.onLoad(); return true; }); } script.onerror = () => { this.constructor.erroredScripts[url] = true; callObserverFuncAndRemoveObserver((observer) => { //7. Call the user's own onError to indicate the loading error observer.onError(); return true; }); }; document.body.appendChild(script); } render() { return null; } }

The component provides the following properties:

onCreate: called when the script tag is created Onerror: triggered when the script is loaded abnormally onLoad:script loading completion trigger. If the URL has been loaded once, the method will be executed directly next time instead of reloading url: link address to load attributes: add html5 custom attribute or id, etc. do not distinguish s

4 May 2020, 10:35 | Views: 1690

Add new comment

For adding a comment, please log in
or create account

0 comments