hupe1980 / react-script-hook

React hook to dynamically load an external script and know when its loaded
MIT License
127 stars 21 forks source link

Testing for script element presence in DOM results in false positives/races #9

Closed timruffles closed 4 years ago

timruffles commented 4 years ago

Adding a script tag to the DOM does not block execution until the script has loaded, so performing this check can result in setting loading to false before the script's onload has fired:

if (document.querySelector(`script[src="${src}"]`)) {
            if (isMounted()) {
                setLoading(false);
            }
            return;
        }
}

If the useEffect wrapping this was only run once we'd be okay, but it's very likely to be run every render. That's because attributes in passed to the useEffects dependency list, and it'll always be a new object per render and thus never equal:

// use-script.tsx
export default function useScript({
  src,
  ...attributes
}: 
  useEffect(() => {
    // ...
  }, [src, attributes, isMounted]);
}