1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
import PropTypes from 'prop-types'
import { useEffect, useMemo, useState } from 'react'
import Modal from './Modal'
import Spinner from './Spinner'
function Loader(props) {
const { load, delay, children } = props
const [state, setState] = useState({
loaded: false,
delayed: false,
timeout: null
})
useEffect(() => {
clearTimeout(state.timeout)
if (!load) {
return
}
const timeout = setTimeout(() => {
if (!state.loaded) {
setState({ ...state, timeout: null, delayed: true })
}
}, delay)
setState({
loaded: false,
delayed: false,
timeout
})
load().then(() => {
clearTimeout(timeout)
setState({ ...state, timeout: null, loaded: true })
})
}, [load])
if (state.loaded) {
return <>{children}</>
} else if (!state.delayed) {
return null
}
return (
<Modal>
<Spinner style={{ color: 'white' }}>
<p>Waiting for API...</p>
</Spinner>
</Modal>
)
}
Loader.propTypes = {
load: PropTypes.func.isRequired,
inline: PropTypes.bool,
delay: PropTypes.number,
}
Loader.defaultProps = {
inline: false,
delay: 200
}
export default Loader
|