usehooks
usehooks copied to clipboard
useScript adds script to cache before it was loaded
Had this issue when I used it.
useScript adds the scripts to the cache before it was loaded. That means that if you in edge cases where you use the useScript twice in the same file. for example one of the scripts will return true before the script was actually loaded.
the fix is just to add to cache once the script loaded.
here is my version of the hook:
import { useEffect, useState } from 'react';
const cachedScripts = new Set();
function useScript(src) {
const [loaded, setLoaded] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
if (cachedScripts.has(src)) {
setLoaded(true);
setError(false);
} else {
const script = document.createElement('script');
script.src = src;
script.async = true;
const onScriptLoad = () => {
cachedScripts.add(src);
setLoaded(true);
setError(false);
};
const onScriptError = () => {
if (cachedScripts.has(src)) {
script.delete();
}
setLoaded(true);
setError(true);
};
script.addEventListener('load', onScriptLoad);
script.addEventListener('error', onScriptError);
document.body.appendChild(script);
return () => {
script.removeEventListener('load', onScriptLoad);
script.removeEventListener('error', onScriptError);
};
}
}, [src]);
return [loaded, error];
}
export default useScript;
I'd also like to add that the initialState could check the cache:
const [state, setState] = useState({
loaded: cachedScripts.has(src),
error: false,
});
This means that code depending on a script can use it on first render if it's already in the cache.