Advertisement

React in 50 Minutes (JNation)

Jun. 16, 2021
Advertisement

More Related Content

Advertisement

React in 50 Minutes (JNation)

  1. R 
 
50
M Maarten
Mulders
(@mthmulders) #reactin50mins
  2. “React
is
a
library
for
declaratively building
user
interfaces
using JavaScript
and
(optionally)
XML. Maarten
Mulders
(@mthmulders) #reactin50mins
  3. R 
 
 No
two-way
data
binding No
templating
language Just
user
interface
(no
routing,
no
HTTP
client) Plain
JavaScript
(or
add
JSX,
TypeScript,
...) Virtual
DOM
vs.
actual
DOM Maarten
Mulders
(@mthmulders) #reactin50mins
  4. M 
J S Maarten
Mulders
(@mthmulders) #reactin50mins
  5. C EUR class
Amount
{ 



constructor(currency,
value)
{ 







this.currency
=
currency; 







this.value
=
value; 



} 



getCurrency()
{ 







return
this.currency; 



} } const
text
=
new
Amount('EUR',
50).getCurrency(); document.getElementById('app').innerText
=
text; 1 2 3 4 5 6 7 8 9 10 11 12 13 Maarten
Mulders
(@mthmulders) #reactin50mins
  6. F true function
isEven(number)
{ 


return
number
%
2
==
0; } const
text
=
isEven(42); document.getElementById('app').innerText
=
text; 1 2 3 4 5 6 Maarten
Mulders
(@mthmulders) #reactin50mins
  7. A 
F true const
isEven
=
(number)
=>
{ 


return
number
%
2
==
0; } const
text
=
isEven(42); document.getElementById('app').innerText
=
text; 1 2 3 4 5 6 Maarten
Mulders
(@mthmulders) #reactin50mins
  8. O 
D Jane
Doe const
person
=
{
name
:
'Jane
Doe',
age:
42,
occupancy:
'JavaScript
dev'
}; const
{
name,
age
}
=
person; const
text
=
name; document.getElementById('app').innerText
=
text; 1 2 3 4 5 Maarten
Mulders
(@mthmulders) #reactin50mins
  9. A 
D two const
numbers
=
[
'one',
'two',
'three'
]; const
[
first,
second
]
=
numbers; const
text
=
second; document.getElementById('app').innerText
=
text; 1 2 3 4 5 Maarten
Mulders
(@mthmulders) #reactin50mins
  10. O 
S 
N {"name":"Jane
Doe","age":42,"occupation":"JS
dev"} const
name
=
'Jane
Doe'; const
age
=
42; const
person
=
{
name,
age,
occupation:
'JS
dev'
}; const
text
=
JSON.stringify(person); document.getElementById('app').innerText
=
text; 1 2 3 4 5 6 Maarten
Mulders
(@mthmulders) #reactin50mins
  11. S 
I USD
150 class
Amount
{ 



constructor(currency,
value)
{ 







this.currency
=
currency; 







this.value
=
value; 



} 



toString()
{ 







return
`this.currency{this.currency}
{this.value}`; 



} } const
text
=
new
Amount('USD',
150).toString(); document.getElementById('app').innerText
=
text; 1 2 3 4 5 6 7 8 9 10 11 12 13 Maarten
Mulders
(@mthmulders) #reactin50mins
  12. B 
JSX Maarten
Mulders
(@mthmulders) #reactin50mins
  13. W 
 
JSX A
syntax
extension
to
JavaScript real
XML,
not
a
string
of
characters allows
embedded
expressions supports
attributes Can
be
nested Automatic
XSS
prevention Needs
to
be
transpiled
to
JavaScript e.g.
React.createElement(...) Maarten
Mulders
(@mthmulders) #reactin50mins
  14. E Elements
can
be
regular
DOM
elements...
(for
now,
but
not
for
long) Hello,
Coimbra const
element
=
<div>Hello,
Coimbra</div> ReactDOM.render(element,
document.getElementById('app')); 1 2 Maarten
Mulders
(@mthmulders) #reactin50mins
  15. A Elements
can
have
attributes... Hello,
Coimbra const
element
=
<div
id='example'>Hello,
Coimbra</div> ReactDOM.render(element,
document.getElementById('app')); 1 2 Maarten
Mulders
(@mthmulders) #reactin50mins
  16. ...
but
they
can
have
different
names
than
HTML
attributes: Hello,
Coimbra const
element
=
<div
className='red­text'>Hello,
Coimbra</div> ReactDOM.render(element,
document.getElementById('app')); 1 2 Maarten
Mulders
(@mthmulders) #reactin50mins
  17. ...
and
they
can
behave
differently: Hello,
Coimbra const
style
=
{
color:
'red',
fontWeight:
'bold'
}; const
element
=
<div
style={
style
}>Hello,
Coimbra</div> ReactDOM.render(element,
document.getElementById('app')); 1 2 3 Maarten
Mulders
(@mthmulders) #reactin50mins
  18. S 
R 
N Values
must
have
a
single
root
node
(or
an
array) x y const
element
=
[<div>x</div>,<div>y</div>] ReactDOM.render(element,
document.getElementById('app')); 1 2 3 Maarten
Mulders
(@mthmulders) #reactin50mins
  19. C Function
that
takes
props
(think:
arguments)
and
returns
a React
element. Hello,
Coimbra const
Greeter
=
(props)
=>
<div>Hello,
Coimbra</div> ReactDOM.render(<Greeter
/>,
document.getElementById('app')); 1 2 Maarten
Mulders
(@mthmulders) #reactin50mins
  20. A 
JSX Maarten
Mulders
(@mthmulders) #reactin50mins
  21. E 
 
JSX The
answer
to
the
ultimate
question
of
life,
universe
and everything:
 42 const
answerToQuestionOfLife
=
40
+
2; const
askQuestionOfLife
=
()
=>
answerToQuestionOfLife; const
Example
=
()
=>
<div> 



The
answer
to
the
ultimate
question
of
life, 



universe
and
everything: 



&nbsp; 



<strong>{
askQuestionOfLife()
}</strong> </div>; ReactDOM.render(<Example
/>,
document.getElementById('app')); 1 2 3 4 5 6 7 8 9 10 Maarten
Mulders
(@mthmulders) #reactin50mins
  22. O 
 
 
 
/
 Hello
World! const
Greeter
=
(props)
=>
<div>Hello
{
props.name
}!</div> ReactDOM.render(<Greeter
name='World'
/>,
document.getElementById('app')); 1 2 Maarten
Mulders
(@mthmulders) #reactin50mins
  23. O 
 
 
 
/
 Alternatively,
using
object
decomposition: Hello
World! const
Greeter
=
({
name
})
=>
<div>Hello
{
name
}!</div> ReactDOM.render(<Greeter
name='World'
/>,
document.getElementById('app')); 1 2 Maarten
Mulders
(@mthmulders) #reactin50mins
  24. C 
 
 
JSX Clapping
hands... const
ClapHands
=
()
=>
<span>Clapping
hands...</span>; const
DryTears
=
()
=>
<span>Drying
tears...</span>; const
ShowEmotion
=
({
happy
})
=>
happy
?
<ClapHands
/>
:
<DryTears
/>; ReactDOM.render(<ShowEmotion
happy={
true
}
/>, 
document.getElementById('app')); 1 2 3 4 5 6 7 Maarten
Mulders
(@mthmulders) #reactin50mins
  25. C 
 
 
JSX
(2) HEIA PHIA const
Ticker
=
({
symbol
})
=>
<div>{
symbol
}</div>; const
TickerList
=
({
symbols
})
=>
symbols.map( 
(symbol)
=>
<Ticker
symbol={
symbol
}
/> ); const
symbols
=
['HEIA',
'PHIA']; ReactDOM.render(<TickerList
symbols={
symbols
}
/>, 
document.getElementById('app')); 1 2 3 4 5 6 7 8 9 Maarten
Mulders
(@mthmulders) #reactin50mins
  26. R 
 M Maarten
Mulders
(@mthmulders) #reactin50mins
  27. A 
 
 So
far,
we've
written
components
and
wired
them
together. Babel
or
tsc
transpiles
them
to
React.createElement(...) invocations: <Greeter
name={
'World'
}
 
 
 /**
transpiles
into
 
 
 React.createElement(Greeter,
{
name:
'World'
},
null)
 Maarten
Mulders
(@mthmulders) #reactin50mins
  28. A 
 
 The
React.createElement
invocations
form
a
tree
of components.
React
maintains
a
virtual
DOM
based
on
your component
tree. The
virtual
DOM
is
compared
to
the
actual
DOM. Only
necessary
changes
are
executed. Maarten
Mulders
(@mthmulders) #reactin50mins
  29. R React
syncs
the
virtual
and
the
actual
DOM
based
on
two assumptions: 1.
If
two
elements
are
of
different
type,
the
(sub)
tree
will
be different. 2.
The
key
prop
identifies
child
elements
over
re-renders. Maarten
Mulders
(@mthmulders) #reactin50mins
  30. 1 
E 
 
 
 
Hallo,
World! const
DutchGreeter
=
({
name
})
=>
<div> 
Hallo,
{
name
}!</div>; const
EnglishGreeter
=
({
name
})
=>
<div> 
Hello,
{
name
}!</div>; const
PortugueseGreeter
=
({
name
})
=>
<div> 
Ei,
{
name
}!</div>; const
App
=
({
lang,
name
})
=>
{ 

switch(lang)
{ 



case
'pt':
return
<PortugueseGreeter
name={
name
}
/> 



case
'nl':
return
<DutchGreeter
name={
name
}
/> 



case
'en': 



default

:
return
<EnglishGreeter
name={
name
}
/> 

} }; ReactDOM.render(<App
name='World'
lang='nl'
/>, 

document.getElementById('app')); 1 2 3 4 5 6 7 8 9 10 11 12 13 Maarten
Mulders
(@mthmulders) #reactin50mins
  31. 2 
T 
KEY
 HEIA PHIA const
Ticker
=
({
symbol
})
=>
<div>{
symbol
}</div>; const
TickerList
=
({
symbols
})
=>
symbols.map( 
(symbol)
=>
<Ticker
key={
symbol
}
symbol={
symbol
}
/> ); const
symbols
=
['HEIA',
'PHIA']; ReactDOM.render(<TickerList
symbols={
symbols
}
/>, document.getElementById('app')); 1 2 3 4 5 6 7 8 9 Maarten
Mulders
(@mthmulders) #reactin50mins
  32. Y 
E 1.
Keeping
state 2.
Reacting
to
events 3.
Fetching
data
over
HTTP 4.
Storing
data Maarten
Mulders
(@mthmulders) #reactin50mins
  33. L 
S 
 
 
C Counter:
0 const
Counter
=
()
=>
{ 


const
[
counter,
setCounter
]
=
React.useState(0); 


return
<div>Counter:
{
counter
}</div> } ReactDOM.render(<Counter
/>,
document.getElementById('app')); 1 2 3 4 5 6 7 Maarten
Mulders
(@mthmulders) #reactin50mins
  34. R 
 
E Similar
to
DOM
event
handling,
but 1.
event
names
are
different:
onClick
vs
onclick. 2.
event
handlers
are
always
functions,
never
strings. 3.
event
handlers
are
bound
to
a
component,
should
not
live globally. 4.
event
handlers
receive
an
synthetic
event
-
browser-agnostic! Maarten
Mulders
(@mthmulders) #reactin50mins
  35. C 
C Counter:
0
 + 
  ‑ const
Counter
=
()
=>
{ 



const
[
counter,
setCounter
]
=
React.useState(0); 



const
increase
=
()
=>
setCounter(counter
+
1); 



const
decrease
=
()
=>
setCounter(counter
­
1); 



return
<div>Counter:
{
counter
}<br
/> 















<button
onClick={
increase
}>


+


</button>
&nbsp; 















<button
onClick={
decrease
}>


­


</button> 










</div> } ReactDOM.render(<Counter
/>,
document.getElementById('app')); 1 2 3 4 5 6 7 8 9 10 11 12 Maarten
Mulders
(@mthmulders) #reactin50mins
  36. C 
C 
 Greet! const
Greeter
=
()
=>
{ 



const
[
name,
setName
]
=
React.useState(''); 



const
updateName
=
(e)
=>
setName(e.target.value); 



const
callback
=
()
=>
alert(`${name}`); 



return
<div><input
type='text'
onChange={
updateName
}
></input><br
/> 















<button
onClick={
callback
}>Greet
{
name
}!</button></div> } ReactDOM.render(<Greeter
/>,
document.getElementById('app')); 1 2 3 4 5 6 7 8 9 10 Maarten
Mulders
(@mthmulders) #reactin50mins
  37. F 
 
 
HTTP What
we
need: 1.
A
bit
of
Plain
Old
JavaScript
to
fetch
some
data 2.
A
component
to
show
the
fetched
data Maarten
Mulders
(@mthmulders) #reactin50mins
  38. 1 
A
 
 
API 
 
 
 
 
 
 
 
 
 
 const
url
=
'https: hqd7fvgovgs2jyoosjgryaylcy.apigateway.eu frankfurt-1.oci
 












.customer oci.com/v1/joke';
 const
getJoke
=
()
 
{
 



return
fetch(url);
 
 
 
 };
 Maarten
Mulders
(@mthmulders) #reactin50mins
  39. 1 
A
 
 
API const
checkStatus
=
(response)
 
{
 



if
(response.status
 
200
 
response.status
<
300)
{
 







return
Promise.resolve(response);
 



}
else
{
 







return
Promise.reject(`HTTP
${response.status}:
${response.statusText}`);
 



}
 };
 
 
 
 const
url
=
'https: hqd7fvgovgs2jyoosjgryaylcy.apigateway.eu frankfurt-1.oci
 












.customer oci.com/v1/joke';
 const
getJoke
=
()
 
{
 



return
fetch(url)
 















.then(checkStatus);
 
 
 };
 Maarten
Mulders
(@mthmulders) #reactin50mins
  40. 1 
A
 
 
API const
checkStatus
=
(response)
 
{
 



if
(response.status
 
200
 
response.status
<
300)
{
 







return
Promise.resolve(response);
 



}
else
{
 







return
Promise.reject(`HTTP
${response.status}:
${response.statusText}`);
 



}
 };
 
 const
parseJson
=
(response)
 
response.json();
 
 const
url
=
'https: hqd7fvgovgs2jyoosjgryaylcy.apigateway.eu frankfurt-1.oci
 












.customer oci.com/v1/joke';
 const
getJoke
=
()
 
{
 



return
fetch(url)
 















.then(checkStatus)
 















.then(parseJson);
 
 };
 Maarten
Mulders
(@mthmulders) #reactin50mins
  41. 1 
A
 
 
API const
checkStatus
=
(response)
 
{
 



if
(response.status
 
200
 
response.status
<
300)
{
 







return
Promise.resolve(response);
 



}
else
{
 







return
Promise.reject(`HTTP
${response.status}:
${response.statusText}`);
 



}
 };
 
 const
parseJson
=
(response)
 
response.json();
 
 const
url
=
'https: hqd7fvgovgs2jyoosjgryaylcy.apigateway.eu frankfurt-1.oci
 












.customer oci.com/v1/joke';
 const
getJoke
=
()
 
{
 



return
fetch(url)
 















.then(checkStatus)
 















.then(parseJson)
 















.then(response
 
response.joke);
 };
 Maarten
Mulders
(@mthmulders) #reactin50mins
  42. 2 
A
 
 
 
 
 
 I
got
arrested
for
downloading
the
whole
of
Wikipedia.
I
said: "Wait,
I
can
explain
everything!" const
RandomJoke
=
()
=>
{ 



const
[
{
joke,
loading
},
setState
]
=
React.useState({
loading:
true
}); 



const
fetchRandomJoke
=
async
()
=>
{ 







//
Does
the
actual
API
call
to
Oracle
Cloud
function,
see
before. 







const
joke
=
await
getJoke(); 







setState({
loading:
false,
joke
}); 



} 



React.useEffect(()
=>
{ 







fetchRandomJoke() 



},
[
]); 



if
(loading)
return
<div>Loading...</div> 



return
<div>{
joke
}</div>; }; ReactDOM.render(<RandomJoke
/>,
document.getElementById('app')); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Maarten
Mulders
(@mthmulders) #reactin50mins
  43. S 
 
 
 
 Local
Storage
&
Session
Storage Part
of
the
 Stores
and
retrieves
string
values Serialise
objects
with
JSON.stringify() Deserialise
with
JSON.parse() Persistent during
browser
session
with
sessionStorage over
browser
shutdowns
with
localStorage Web
Storage
API Maarten
Mulders
(@mthmulders) #reactin50mins
  44. D 
A 1.
Debugging 2.
Testing 3.
Building Maarten
Mulders
(@mthmulders) #reactin50mins
  45. D Install
the
React
Developer
Tools
for
your
browser
of
choice. Maarten
Mulders
(@mthmulders) #reactin50mins
  46. I 
C 
T Maarten
Mulders
(@mthmulders) #reactin50mins
  47. D Maarten
Mulders
(@mthmulders) #reactin50mins
  48. T 
 
 Use
Jest
(test
platform
&
library)
and
(React)
Testing
Library (testing
utilities) Render
a
React
component
in
a
unit
test Make
assertions
about
its
output
and
behaviour Maarten
Mulders
(@mthmulders) #reactin50mins
  49. T 
 
 
C import
{
render,
screen
}
from
'@testing library/react'
 
 describe('<Greeter
 ',
()
 
{
 



it('should
render
text',
()
 
{
 







render(<Greeter
name='JNation'
 );
 







expect(screen.getByText(/hello,
jnation/i)).toBeVisible();
 



});
 });
 Maarten
Mulders
(@mthmulders) #reactin50mins
  50. T 
B 
 
 
C import
{
f reEvent,
render,
screen
}
from
'@testing library/react'
 
 describe('<AwesomeButton
 ',
()
 
{
 



it('should
invoke
action
on
click',
()
 
{
 







const
callback
=
jest.mock();
 







render(<AwesomeButton
action={
callback
}
 );
 







f reEvent.click(screen.getByRole('link'));
 







expect(dummy).toHaveBeenCalled();
 



});
 });
 Maarten
Mulders
(@mthmulders) #reactin50mins
  51. D 
 
S 
 
 tl;dr:
use
 
(CRA) Uses
Webpack,
Babel,
ESLint
and
a
dozen
of
other
tools Tested
to
work
together Live-reloading
of
changed
code Source
maps
for
easy
debugging Have
an
ready-to-go
app
in
one
command Create
React
App npx
create react app
my next killer app
 
 
or
 
 npm
i
 g
create react app
 create react app
my next killer app
 Maarten
Mulders
(@mthmulders) #reactin50mins
  52. U 
CRA npm
run
start
to
start
developing npm
run
build
to
create
a
production
build npm
run
test
to
run
unit
tests Maarten
Mulders
(@mthmulders) #reactin50mins
  53. G 
B Maarten
Mulders
(@mthmulders) #reactin50mins
  54. T 
R 
 
(C )
H 1.
Name
must
start
with
use! 2.
Only
use
in
React
function
components not
in
classes not
outside
React
components Maarten
Mulders
(@mthmulders) #reactin50mins
  55. C 
H Why
do
programmers
prefer
dark
mode?
Because
light attracts
bugs. const
useRandomJoke
=
()
=>
{ 



const
[
{
joke,
loading
},
setState
]
=
React.useState({
loading:
true
}); 



const
fetchRandomJoke
=
async
()
=>
{ 







const
joke
=
await
getJoke(); 







setState({
loading:
false,
joke
}); 



} 



React.useEffect(()
=>
{
fetchRandomJoke()
},
[
]); 



return
{
loading,
joke
}; }; const
RandomJoke
=
({

})
=>
{ 



const
{
joke,
loading
}
=
useRandomJoke() 



if
(loading)
return
<div>Loading...</div>; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
 Maarten
Mulders
(@mthmulders) #reactin50mins
  56. R 
18:
N 
R 
API From
React
18
on,
you
can
use
a
new
Root
API. L 
R 
API (will
continue
to
work,
but
will
eventually
be
deprecated) N 
R 
API ReactDOM.render(<App
 ,
document.getElementById('root'));
 const
root
=
ReactDOM.createRoot(document.getElementById('root'));
 root.render(<App
 );
 Maarten
Mulders
(@mthmulders) #reactin50mins
  57. R 
18:
S Suspense
lets
you
"wait"
for
some
code
or
data
to
load
specify
a loading
state
in
the
meantime: Here,
SomeComponentThatSuspends
can
be 1.
a
lazily
loaded
component
(using
React.lazy()). 2.
a
component
that
renders
while
the
network
request
is
still running. <Suspense
fallback={<Loading
 }>
 

<SomeComponentThatSuspends
 
 Suspense>
 Maarten
Mulders
(@mthmulders) #reactin50mins
  58. R 
18:
U 
 
 Distinguish
between
urgent
updates
(typing,
hover,
dragging, ...)
and
UI
transitions
(slowed
down
by
expensive
rendering, slow
network...). Wrap
a
non-urgent
updates
in
startTransition,
so
an
urgent update
can
interrupt
it.
React
will
discard
stale
rendering
work and
render
only
the
latest
update. Maarten
Mulders
(@mthmulders) #reactin50mins
  59. T 
 Use
Create
React
App Think
in
(small)
components Think
declaratively U 
 Create
React
App:
 Dad
Jokes
API:
 https://bit.ly/c-r-a https://bit.ly/dad-joke-api Maarten
Mulders
(@mthmulders) #reactin50mins
Advertisement