UNPKG

@cp949/mui

Version:

CP949 MUI React component library

63 lines (50 loc) 1.78 kB
import { useEffect, useRef, useState } from 'react'; type LoadingState = 'unknown' | 'loading' | 'ready' | 'error'; export function useScript( src: string, options: { removeOnUnmount?: boolean } = { removeOnUnmount: false }, ): LoadingState { const [status, setStatus] = useState<LoadingState>('loading'); const optionsRef = useRef(options); useEffect(() => { const prevScript = document.querySelector(`script[src="${src}"]`) as HTMLScriptElement | null; const domStatus = prevScript?.getAttribute('data-status'); if (domStatus) { setStatus(domStatus as LoadingState); return; } if (prevScript === null) { const script = document.createElement('script') as HTMLScriptElement; script.src = src; script.async = true; script.setAttribute('data-status', 'loading'); document.body.appendChild(script); const handleScriptLoad = () => { script.setAttribute('data-status', 'ready'); setStatus('ready'); removeEventListeners(); }; const handleScriptError = () => { script.setAttribute('data-status', 'error'); setStatus('error'); removeEventListeners(); }; const removeEventListeners = () => { script.removeEventListener('load', handleScriptLoad); script.removeEventListener('error', handleScriptError); }; script.addEventListener('load', handleScriptLoad); script.addEventListener('error', handleScriptError); const removeOnUnmount = optionsRef.current.removeOnUnmount; return () => { if (removeOnUnmount === true) { script.remove(); removeEventListeners(); } }; } else { setStatus('unknown'); } }, [src]); return status; }