-
Notifications
You must be signed in to change notification settings - Fork 1
/
2024-06-23-weblab-notes:-react-hooks.html
248 lines (244 loc) · 14 KB
/
2024-06-23-weblab-notes:-react-hooks.html
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="description" content="This is a personal note for the [[https://docs.google.com/presentation/d/1n5RlpgBtXQ1OHvutx9TRLotWizyg2BPKv_780DD4-90/edit#slide=id.gb2bbafee77_1_66][web.lab lectures]].">
<link rel="alternate"
type="application/rss+xml"
href="https://chenyo.me/rss.xml"
title="RSS feed for https://chenyo.me">
<title>Weblab notes: React hooks</title>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'],['\\(','\\)']]}});
</script>
<meta name="author" content="chenyo">
<meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="assets/style.css" type="text/css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"/>
<link rel="favicon" type="image/x-icon" href="favicon.ico">
<script src="assets/search.js"></script></head>
<body>
<div id="preamble" class="status">
<header>
<h1><a href="https://chenyo.me">Chenyo's org-static-blog</a></h1>
<nav>
<a href="https://chenyo.me">Home</a>
<a href="archive.html">Archive</a>
<a href="tags.html">Tags</a>
<div id="search-container">
<input type="text" id="search-input" placeholder="Search anywhere...">
<i class="fas fa-search search-icon"></i>
</div>
</nav>
</header></div>
<div id="content">
<div class="post-date">23 Jun 2024</div><h1 class="post-title"><a href="https://chenyo.me/2024-06-23-weblab-notes:-react-hooks.html">Weblab notes: React hooks</a></h1>
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgc402bc2">1. What is a React hook</a>
<ul>
<li><a href="#orgb7734bd">1.1. <code>useState</code> is not enough</a></li>
<li><a href="#org105bbc4">1.2. <code>useEffect</code> runs after specific variable change</a></li>
</ul>
</li>
<li><a href="#orgcf0fd04">2. React hook patterns</a>
<ul>
<li><a href="#org5d7091e">2.1. Fetch and send data</a></li>
<li><a href="#org33f284a">2.2. Conditional rendering</a></li>
<li><a href="#org202802a">2.3. Render an array of Data</a></li>
</ul>
</li>
<li><a href="#org3928f43">3. Example: Stopwatch</a></li>
<li><a href="#org84c621c">4. DOM and component mounting</a></li>
</ul>
</div>
</nav>
<p>
This is a personal note for the <a href="https://docs.google.com/presentation/d/1n5RlpgBtXQ1OHvutx9TRLotWizyg2BPKv_780DD4-90/edit#slide=id.gb2bbafee77_1_66">web.lab lectures</a>.
</p>
<div id="outline-container-orgc402bc2" class="outline-2">
<h2 id="orgc402bc2"><span class="section-number-2">1.</span> What is a React hook</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>Special functions to access parts of the component lifestyle.</li>
<li>e.g., <code>useState</code></li>
</ul>
</div>
<div id="outline-container-orgb7734bd" class="outline-3">
<h3 id="orgb7734bd"><span class="section-number-3">1.1.</span> <code>useState</code> is not enough</h3>
<div class="outline-text-3" id="text-1-1">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #51afef;">const</span> [<span style="color: #dcaeea;">persons</span>, <span style="color: #dcaeea;">setPersons</span>] = useState([]);
<span class="linenr">2: </span>
<span class="linenr">3: </span>testingStuff = () => {
<span class="linenr">4: </span> <span style="color: #5B6268;">/* </span><span style="color: #5B6268;">assume persons is empty before</span><span style="color: #5B6268;"> */</span>
<span class="linenr">5: </span> setPersons([...persons, <span style="color: #98be65;">"me"</span>]);
<span class="linenr">6: </span>}
<span class="linenr">7: </span>console.log(persons);
</pre>
</div>
<ul class="org-ul">
<li>The output of <code class="src src-js">console.log</code> is <code>[]</code> instead of <code>["me"]</code> because setting a state is <b><b>async</b></b>!</li>
<li>To do something immediately after a state is changed, use <code>useEffect</code> hook!</li>
</ul>
</div>
</div>
<div id="outline-container-org105bbc4" class="outline-3">
<h3 id="org105bbc4"><span class="section-number-3">1.2.</span> <code>useEffect</code> runs after specific variable change</h3>
<div class="outline-text-3" id="text-1-2">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span>useEffect(() => {
<span class="linenr">2: </span> console.log(persons);
<span class="linenr">3: </span>}, [persons]);
</pre>
</div>
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span>useEffect(() => {
<span class="linenr">2: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">do something, e.g., interact with an external service</span><span style="color: #5B6268;"> */</span>
<span class="linenr">3: </span>
<span class="linenr">4: </span><span style="color: #51afef;">return</span> () => {
<span class="linenr">5: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">cleanup function on dismount, e.g., disconnect from external service</span><span style="color: #5B6268;"> */</span>
<span class="linenr">6: </span>}
<span class="linenr">7: </span>}, [<span style="color: #5B6268;">/*</span><span style="color: #5B6268;">dependencies</span><span style="color: #5B6268;"> */</span>])
</pre>
</div>
<ul class="org-ul">
<li><code class="src src-js">useEffect(myFunction, [var1, var2])</code> calls <code>myFunction</code> everytime when <code>var1</code> or <code>var2</code> changes</li>
<li><code class="src src-js">useEffect(myFunction, []])</code> calls only once when the component is rendered for the first time (on mount)</li>
<li><code class="src src-js">useEffect(myFunction)</code> calls at every render</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orgcf0fd04" class="outline-2">
<h2 id="orgcf0fd04"><span class="section-number-2">2.</span> React hook patterns</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-org5d7091e" class="outline-3">
<h3 id="org5d7091e"><span class="section-number-3">2.1.</span> Fetch and send data</h3>
<div class="outline-text-3" id="text-2-1">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">fetch data on mount</span><span style="color: #5B6268;"> */</span>
<span class="linenr">2: </span>useEffect(() => {
<span class="linenr">3: </span> get(<span style="color: #98be65;">"/api/packages"</span>).then((packageList) => {
<span class="linenr">4: </span> setPackages(packageList);
<span class="linenr">5: </span> });
<span class="linenr">6: </span>}, []);
</pre>
</div>
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;">send data then toggle admin state</span><span style="color: #5B6268;"> */</span>
<span class="linenr">2: </span><span style="color: #51afef;">const</span> <span style="color: #dcaeea;">handleToggleAdmin</span> = () => {
<span class="linenr">3: </span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">.then(), do something once the promise is fulfilled</span>
<span class="linenr">4: </span> post(<span style="color: #98be65;">"/api/user/admin"</span>, { admin: !admin }).then(() => {
<span class="linenr">5: </span> setAdmin(!admin);
<span class="linenr">6: </span> });
<span class="linenr">7: </span>};
<span class="linenr">8: </span><span style="color: #5B6268;">/* </span><span style="color: #5B6268;"><Button onClick={handleToggleAdmin}</span><span style="color: #5B6268;"> */</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org33f284a" class="outline-3">
<h3 id="org33f284a"><span class="section-number-3">2.2.</span> Conditional rendering</h3>
<div class="outline-text-3" id="text-2-2">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">JSX is a way of writing HTML in js</span>
<span class="linenr">2: </span><span style="color: #51afef;">let</span> <span style="color: #dcaeea;">content</span> = loading ? <p>Loading...</p> : <p>Loaded</p>;
<span class="linenr">3: </span><span style="color: #51afef;">return</span> (
<span class="linenr">4: </span> <div>
<span class="linenr">5: </span> <h1>Title</h1>
<span class="linenr">6: </span> {content}
<span class="linenr">7: </span> </div>
<span class="linenr">8: </span>);
</pre>
</div>
</div>
</div>
<div id="outline-container-org202802a" class="outline-3">
<h3 id="org202802a"><span class="section-number-3">2.3.</span> Render an array of Data</h3>
<div class="outline-text-3" id="text-2-3">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr">1: </span><span style="color: #51afef;">const</span> <span style="color: #dcaeea;">data</span> = [
<span class="linenr">2: </span> { id: <span style="color: #da8548; font-weight: bold;">0</span>, text: <span style="color: #98be65;">"Text 1"</span> },
<span class="linenr">3: </span> { id: <span style="color: #da8548; font-weight: bold;">1</span>, text: <span style="color: #98be65;">"Text 2"</span> },
<span class="linenr">4: </span>];
<span class="linenr">5: </span><span style="color: #5B6268;">// </span><span style="color: #5B6268;">render a component for each data item</span>
<span class="linenr">6: </span><span style="color: #51afef;">return</span> data.map((item) => (
<span class="linenr">7: </span> <ItemComponent key={item.id}>{item.text}</ItemComponent>
<span class="linenr">8: </span>));
</pre>
</div>
<ul class="org-ul">
<li><code>key</code> is a special prop in React; it is used identify which item has changed efficiently</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org3928f43" class="outline-2">
<h2 id="org3928f43"><span class="section-number-2">3.</span> Example: Stopwatch</h2>
<div class="outline-text-2" id="text-3">
<div class="org-src-container">
<pre class="src src-js"><span class="linenr"> 1: </span><span style="color: #51afef;">const</span> <span style="color: #dcaeea;">Stopwatch</span> = () => {
<span class="linenr"> 2: </span> <span style="color: #51afef;">const</span> [<span style="color: #dcaeea;">time</span>, <span style="color: #dcaeea;">setTimer</span>] = useState(<span style="color: #da8548; font-weight: bold;">0</span>);
<span class="linenr"> 3: </span>
<span class="linenr"> 4: </span> useEffect(() => {
<span class="linenr"> 5: </span> <span style="color: #51afef;">const</span> <span style="color: #dcaeea;">timer</span> = setInterval(() => {
<span class="linenr"> 6: </span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">setTimer accepts either a new state value,</span>
<span class="linenr"> 7: </span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">or a function that takes the previous state (oldTime) as an argument and returns the new state</span>
<span class="linenr"> 8: </span> setTime((oldTime) => oldTime + <span style="color: #da8548; font-weight: bold;">1</span>);}, <span style="color: #da8548; font-weight: bold;">1000</span>);
<span class="linenr"> 9: </span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">if not properly cleanup after unmounting</span>
<span class="linenr">10: </span> <span style="color: #5B6268;">// </span><span style="color: #5B6268;">the timer will continue to run even the state no longer exists</span>
<span class="linenr">11: </span> <span style="color: #51afef;">return</span> () => clearInterval(timer);
<span class="linenr">12: </span> }, []);
<span class="linenr">13: </span> <span style="color: #51afef;">return</span> <>TIme: {time}</>;
<span class="linenr">14: </span>};
</pre>
</div>
</div>
</div>
<div id="outline-container-org84c621c" class="outline-2">
<h2 id="org84c621c"><span class="section-number-2">4.</span> DOM and component mounting</h2>
<div class="outline-text-2" id="text-4">
<ul class="org-ul">
<li>DOM (Document Object Model): a programming interface for web documents; represents the structure of a document, e.g., HTML, as a tree of objects, where each object corresponds to a part of the document; it dynamically updates the document contents
<ul class="org-ul">
<li>React is a framework that manipulates DOM</li>
</ul></li>
<li>A React component is unmounted when:
<ul class="org-ul">
<li>conditional rendering</li>
<li>routing; navigating from one route to another</li>
<li>its parent component is unmounted</li>
</ul></li>
</ul>
</div>
</div>
<div class="taglist"><a href="https://chenyo.me/tags.html">Tags</a>: <a href="https://chenyo.me/tag-study.html">study</a> <a href="https://chenyo.me/tag-web.html">web</a> <a href="https://chenyo.me/tag-react.html">react</a> <a href="https://chenyo.me/tag-mit.html">mit</a> </div></div>
<div id="postamble" class="status"><div id="search-results"></div>
<footer>
<div class="footer-content">
<div class="footer-left">
<p>© 2024 chenyo. Some rights reserved.</p>
<a rel="license" href="http://creativecommons.org/licenses/by-nc/4.0/">
<img alt="Creative Commons License" style="border-width: 0"
src="https://i.creativecommons.org/l/by-nc/4.0/88x31.png"/>
</a>
</div>
<div class="social-links">
<a href="https://t.me/chenyo17" target="_blank" rel="noopener noreferrer">
<i class="fab fa-telegram"></i>
</a>
<a href="https://github.com/chenyo-17" target="_blank" rel="noopener noreferrer">
<i class="fab fa-github"></i>
</a>
</div>
</footer></div>
</body>
</html>