-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLevel1.js
140 lines (119 loc) · 3.92 KB
/
Level1.js
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { useEffect, useState } from "react"
import { colorMe } from "../../utils/colorFunc"
import hasCode from "../../utils/hasCode"
import { getTimestamp } from "../../utils/misc"
import level1Styles from './styles/level1.module.css' /* level1Styles from './styles/level1.module.css' */
/* //> DEV NOTES
* Tested use of AbortController to fetch data only ONCE
- Successful in only getting data ONCE
- 1st fetch was aborted -- abort() at useEffect end catches up to 1st fetch
- 2nd fetch (due to useEffect running a second time) is persists
1st pre-fetch initialization - [03:53]-[46.952] +
abort signal reason sent/received - [03:53]-[46.969]
2nd pre-fetch initialization - [03:53]-[46.990] -
fetched data received - [03:53]-[47.377] + 0.425 [from 1st pre-fetch]
- 0.387 [from 2nd pre-fetch]
! 0.038 [wasted in 1st fetch]
? TEST with react-query if it is more efficient
*/
const { qnaFetching, qnaContainer } = level1Styles
const QnaDetails = ({
q: {
_id,
question,
answer,
list,
},
backgroundColor
}) => {
return (
<details>
<summary style={{ backgroundColor }}>{question}</summary>
<div>
<p style={{ margin: '0' }}>{hasCode(answer)}</p>
{
list && (
<ul>
{
list.map((li, liIdx) => <li key={_id + liIdx}>{hasCode(li)}</li>)
}
</ul>
)
}
</div>
</details>
)
}
const Level1 = () => {
const [loading, setLoading] = useState(true)
const [qna, setQna] = useState([
{
_id: '',
question: '',
answer: '',
list: [''],
}
])
useEffect(() => {
/* //> NOTICE that fetch URL is one directory up
Reason: current location when fetching is `{baseURL}/exercises/level1` */
const URL = '../data/level1qna.json'
/* ========================================================================= */
console.count('useEffect')
console.log(getTimestamp('useEffect'))
const controller = new AbortController()
/* adding custom timestamp */
controller.signal.idesmarTimeStamp = getTimestamp()
console.table(controller.signal)
/* //> fetch using promise chaining
fetch(URL, { signal: controller.signal })
.then(res => res.json())
.then(data => {
console.count('fetched data in promise chaining')
setQna(prev => data)
})
.catch(err => console.log(err))
*/
const fetchData = async () => {
try {
const res = await fetch(URL, { signal: controller.signal })
console.log(getTimestamp('--- FETCHED DATA ---'),'in async function')
const data = await res.json()
setQna(prev => data)
setLoading(prev => false)
}
catch (err) {
/* aborted fetch */
// throw err
console.log(getTimestamp('err'), err)
}
}
fetchData()
return () => {
/* //> timestamp comparison to prove abort is applied at 1st useEffect
timestamp below and the UPDATED controller.signal.reason (on FIRST useEffect) which contains a getTimestamp --- shows that the abort method was applied to it */
console.log(getTimestamp('return cleanup function'))
/* //> aborts the initial fetch to only fetch data ONCE */
controller.abort(`${getTimestamp('Run only once')}`)
}
/* ========================================================================= */
}, [])
const backgroundColor = colorMe('dark')
return (
<div>
<h1>Level 1</h1>
<div className={loading ? qnaFetching : qnaContainer}>
{
qna.map(q =>
<QnaDetails
key={q._id}
q={q}
backgroundColor={backgroundColor}
/>
)
}
</div>
</div>
)
}
export { Level1 }