useState() hook to create a state variable for the load status of the script.useEffect() hook to handle all the logic for loading and unloading the script anytime the src changes.src value is present, set the status to 'idle' and return.Document.querySelector() to check if a <script> element with the appropriate src value exists.Document.createElement() to create one and give it the appropriate attributes.data-status attribute as a way to indicate the status of the script, setting it to 'loading' initially.status from its data-status attribute. This ensures that no duplicate element will be created.EventTarget.addEventListener() to listen for 'load' and 'error' events and handle them by updating the data-status attribute and the status state variable.Document.removeEventListener() to remove any listeners bound to the element.const useScript = src => { const [status, setStatus] = React.useState(src ? 'loading' : 'idle'); React.useEffect(() => { if (!src) { setStatus('idle'); return; } let script = document.querySelector(`script[src="${src}"]`); if (!script) { script = document.createElement('script'); script.src = src; script.async = true; script.setAttribute('data-status', 'loading'); document.body.appendChild(script); const setDataStatus = event => { script.setAttribute( 'data-status', event.type === 'load' ? 'ready' : 'error' ); }; script.addEventListener('load', setDataStatus); script.addEventListener('error', setDataStatus); } else { setStatus(script.getAttribute('data-status')); } const setStateStatus = event => { setStatus(event.type === 'load' ? 'ready' : 'error'); }; script.addEventListener('load', setStateStatus); script.addEventListener('error', setStateStatus); return () => { if (script) { script.removeEventListener('load', setStateStatus); script.removeEventListener('error', setStateStatus); } }; }, [src]); return status; };
const script =
'data:text/plain;charset=utf-8;base64,KGZ1bmN0aW9uKCl7IGNvbnNvbGUubG9nKCdIZWxsbycpIH0pKCk7';
const Child = () => {
const status = useScript(script);
return <p>Child status: {status}</p>;
};
const MyApp = () => {
const status = useScript(script);
return (
<>
<p>Parent status: {status}</p>
<Child />
</>
);
};
ReactDOM.render(<MyApp />, document.getElementById('root'));Subscribe to get resources directly to your inbox. You won't receive any spam! ✌️