Dynamic Script Loading in React with Hooks

Published on 4 June 2020

This post describes how to dynamically load a script by adding a script tag to your document using React Hooks.

This is a modification on the code presented in this article. The script adds a script tag to the page and optionally calls a callback. It will not add the script again if it is already loaded. If a callback was provided, then it removes the script from the page when the component unmounts (so that the callback can be called again).

/**
 * Dynamic script loading hook.
 */
import React from 'react';

// If no callback is provided, the script will not be removed on unmount. This
// kinda matters if the script loading is not idempotent (for some reason
// MathJax is not, which is one of the scripts I was using this for) or
// if you need the callback to happen again.
const useScript = (
  scriptUrl: string,
  scriptId: string,
  callback?: () => void
) => {
  React.useEffect(() => {
    const existingScript = document.getElementById(scriptId);

    if (!existingScript) {
      const script = document.createElement('script');
      script.src = scriptUrl;
      script.id = scriptId;
      document.body.appendChild(script);

      script.onload = () => {
        if (callback) {
          callback();
        }
      };
    }

    if (existingScript && callback) {
      callback();
    }

    return () => {
      if (existingScript && callback) {
        existingScript.remove();
      }
    };
  }, [scriptUrl, scriptId]);
};

export default useScript;

Comments