Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 2262a39

Browse files
committed
feat(hooks): add useScript to load 3rd script
1 parent 73a752f commit 2262a39

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

components/Hooks/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { default as useShortcut } from './useShortcut'
22
export { default as useMedia } from './useMedia'
33
export { default as usePlatform } from './usePlatform'
4+
export { default as useScript } from './useScript'

components/Hooks/useScript.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { useState, useEffect } from 'react'
2+
3+
const cachedScripts = []
4+
5+
const useScript = src => {
6+
// Keeping track of script loaded and error state
7+
const [state, setState] = useState({
8+
loaded: false,
9+
error: false,
10+
})
11+
12+
useEffect(
13+
() => {
14+
// If cachedScripts array already includes src that means another instance ...
15+
// ... of this hook already loaded this script, so no need to load again.
16+
if (cachedScripts.includes(src)) {
17+
setState({
18+
loaded: true,
19+
error: false,
20+
})
21+
} else {
22+
cachedScripts.push(src)
23+
24+
// Create script
25+
const script = document.createElement('script')
26+
script.src = src
27+
script.async = true
28+
29+
// Script event listener callbacks for load and error
30+
const onScriptLoad = () => {
31+
setState({
32+
loaded: true,
33+
error: false,
34+
})
35+
}
36+
37+
const onScriptError = () => {
38+
// Remove from cachedScripts we can try loading again
39+
const index = cachedScripts.indexOf(src)
40+
if (index >= 0) cachedScripts.splice(index, 1)
41+
script.remove()
42+
43+
setState({
44+
loaded: true,
45+
error: true,
46+
})
47+
}
48+
49+
script.addEventListener('load', onScriptLoad)
50+
script.addEventListener('error', onScriptError)
51+
52+
// Add script to document body
53+
document.body.appendChild(script)
54+
55+
// Remove event listeners on cleanup
56+
return () => {
57+
script.removeEventListener('load', onScriptLoad)
58+
script.removeEventListener('error', onScriptError)
59+
}
60+
}
61+
},
62+
[src] // Only re-run effect if script src changes
63+
)
64+
65+
return [state.loaded, state.error]
66+
}
67+
68+
export default useScript

0 commit comments

Comments
 (0)