bob's role is one of the most viewed
react instructors in the world
and now he's back with a brand new
complete react course that will teach
you modern react using patterns like
functional components and hooks
if you want to learn the react
javascript library this is the video
hey free code campers welcome to my
newest course on learning react
in this course you're going to solve
over 140 different coding challenges and
work on eight different projects all of
which have an associated figma design
file to guide your work
and you actually have two options for
following along either by using your
local machine i actually have a few
lessons that will show you how to do
that starting pretty early in this
course
or you can head over to scrimba.com
where there's an interactive version of
this course so that you can solve the
challenges directly in your browser
it's totally up to you what you want to
do the link to the course on
scrimmage.com is provided below
and actually this course is part of a
larger front-end career path which we
have at scrimba which takes people from
zero to hirable as a front-end developer
this course is module 11 in that career
path and my more advanced react course
immediately follows this free react
course as module 12 where i go even more
in depth into react react router using
the context api and so much more if
those topics sound confusing to you
don't worry at all you don't need to
take them to understand this course
now i always appreciate any feedback you
have for me about the course so you're
welcome to reach out to me on twitter at
bobsarole or if you have any questions
about your specific code the best place
for those is to either reach out to the
free codecamp forums or discord server
or you can check out scrimba's own
discord server which is becoming a more
and more deeply integrated part of the
whole scrimba.com experience
and with that good luck and have a ton
of fun learning react
hey there and welcome to the learn react
module i'm super excited you're joining
me for this course because by the end
you'll have built not one not two but at
least eight projects using react there's
so many of them i don't even have time
to go over each one of them in detail
right now i could barely even fit them
on this slide so why are we doing so
many projects well it's because i
designed the curriculum for this course
to be project driven in each of the
sections we will start with a goal
project that we are working toward and
then we'll learn everything we need in
order to build that project now in order
for that approach to actually work i'm
going to be asking a lot from you so
let's talk for just a bit on how you can
get the most from this course
just like everything in life what you
put into this course is what you will
get out of it or as i like to say my
philosophy about learning is that the
easiest way to learn something is to do
it the hard way in this course i'm going
to be asking you to do a lot of the work
for much of it you'll have me there
after each challenge to walk you through
a solution but for some of it you won't
either way what i'm asking of you now is
to avoid the trap of tutorial hell where
you end up passively watching me do all
the work remember this is not school
you're presumably here because you
actually want to finish the course with
the ability to write react code by
yourself
school has taught a lot of us that the
goal of learning is to get a good grade
in fact i heard something really
interesting that said that education is
the only thing that humans try to get
less out of than what they paid for so
don't let that be you in this course if
you really give it everything you've got
meaning you do all the challenges and
projects you're involved with the
community and you are an active
participant in your own learning i can
promise that you'll probably finish off
in a better spot than many students
getting their degree in computer science
and i really don't say that lightly
along those lines remember that space
learning and repetition are your best
friends binging the course from
beginning to end even if you are doing
all the assignments is kind of like
trying to run an ultra marathon without
training your brain actually needs rest
so take breaks often by taking this
course the goal isn't just to get to the
end it's to get to the end with some
honest-to-goodness react skills then
after you come back to this course on
maybe the next day don't be afraid to
re-watch some of the past lessons and
even redo some of the past challenges
because repetition really is your best
friend whenever you're trying to learn
something new
so what should you already know coming
into this course before jumping into
react you should have a solid grasp of
the fundamentals of web development
namely html css javascript and
preferably a pretty solid understanding
of the new syntax that was introduced
back in ecmascript 6 es6 and above
if you're feeling at all rusty on any of
these topics you can click the logo for
each one of these which will send you to
another free course here on scrimba
where you can brush up on those skills
my name is bob zaroll i'm going to be
your instructor throughout this whole
course my username pretty much
everywhere online is bob zaroll but
these days i'm really most active on
twitter you can click the twitter icon
to go to my profile if you want to
follow me that would be great and so
without any further delay let's jump
right in and start learning react
in the first section of this course
we're going to be learning everything we
need in order to build a basic static
page using react and i know what you
might be thinking but i already know how
to make static web pages i know you're
probably super excited to really dive in
and learn dynamic web applications with
react and we are going to get there in
this course but in order to start off
this section is all about learning the
basic syntax and you could say the
vocabulary of react because i found that
the best approach to learning react is
to first start learning how to think in
react
the reason for this is because react
really does kind of change the game in
terms of how you build applications
later in this section we are going to
start learning the differences between
declarative and imperative programming
and you're going to find that react
approaches web development in a
completely different way so the point is
we're first going to be dialing in our
brains to start thinking in terms of
using react to build websites by first
building some static web pages not
unlike the ones that you normally would
just use html and css for so this might
not seem terribly exciting right now but
i think you'll soon see that writing
composable reusable components in react
can actually be a bit addicting and
pretty fun
so i know that you'll find a lot of
benefit in starting off with the milk
before we get to the meat or of course
we have a vegetarian option as well
the content in this section will be
driven forward by the goal of creating
our first static web page in react and
that's the page you see here in the
screenshot that has a list of fun facts
about react now this screenshot is
actually also a link to the figma file
for the design of this page so if you
click this screenshot it will open up in
figma you'll have to make sure that you
log into your figma account if you don't
have one yet it's free to create and
clicking the screenshot will lead you to
a sort of shared file that everyone will
have access to
in that shared file you'll see something
near the top that looks kind of like
this where it's got react facts and then
this little drop down arrow your best
bet is going to be to click that drop
down arrow go over to duplicate to your
drafts and click that
duplicating this design to your own
drafts is going to make it possible for
you not only to edit the design if you
want to change it a little bit but also
to help you avoid any distraction you
might see on the design page of anybody
else's cursors or maybe some comments
that they may have left
so i'll go back to this design here make
sure to click on it now so at least the
url gets saved up in your tabs in your
browser
and lastly we're going to look at the
different topics that we'll be covering
in this section
so what are we going to learn about well
first we're going to learn why we even
care about react in the first place i
think knowing why react is so exciting
and so popular will help make your
learning journey of react a much simpler
one because you'll be so excited about
what you'll be able to create in the end
by using react
we'll also be talking about a
proprietary react syntax called jsx and
we'll get to see how that sort of
changed the game for react and made
writing react a much more familiar
experience
then we'll dive into creating custom
components and you'll learn all about
what that means and how to actually do
that yourself in react
and of course in order to build our
project we're going to need to know how
to apply css styling
again the goal is for us to be able to
build this simple static page in react
i'm really excited for us to get started
so without any further ado let's jump
right into the deep end and start
writing our first react code
before we just jump right into theory
and why we care about react and how all
the little pieces of react work i want
to get your hands on the keyboard typing
some react code as soon as possible
mostly just to show you that react is
not a scary library to be working with
so let's see how we can set up react now
i like to think of there as being an
easy way to set up react in your project
and a correct way of setting react up in
your project for our sake in learning
we're going to start with the easy way
which will also make it so that you can
actually just do this in your local
environment hopefully you're following
along here on scrimba.com but if you're
curious and you're interested you can
always do this on your local environment
as well now you can see i have a very
basic html page set up i have nothing in
my javascript at all my css is minimal
and we're going to walk through this
together now i have some slides here and
you can actually click on this
screenshot and that will send you to
this exact page in the react
documentation it tells you how you can
include react into your project and we
can actually pull in these libraries
that we need straight from a cdn in
other words we can just copy these two
script tags here and start writing react
code there's a little more to it but
what i'm going to do is click here and
that's going to open me up to the react
page i'm just going to copy the two
script tags that you can see
and over in my index html i'm going to
put it in the head here
let me fix the indentation and i've
pulled in the react library and another
library called react dom theoretically
this is all i need in order to start
writing some react code now i'm going to
take it one step further and that's
because just pulling and reacting react
dom is going to be pretty extremely
limiting in terms of using the power of
react unless we also pull in something
called babble i'm not gonna jump in too
deep into why we need to pull in babel
for now all i'm going to do is click on
this screenshot here which will take me
again to a page where i can copy the
script tag that you see
and i will paste that in underneath this
script tag and if we look really closely
below here it says you can use any jsx
we'll cover what jsx is later in any
script tag by adding type equals text
slash babble so i'm going to do that
here in my script tag down here type
equals text slash babble
and that's all the setup we really need
by pulling in the react
dom library in this script tag i now
have access to a global variable called
react dom i'm going to use that to
render something to the screen once
again i'm going to be covering
everything that we're talking about here
it's totally okay if this is moving
pretty quickly reactdom.render allows me
to render something that looks very much
like html now this might be blowing your
mind a little bit because it probably
looks a little strange writing some html
inside of my javascript we're going to
see how this is kind of one of the
beautiful things that react has added so
that we can write really declarative
code now let's put something inside this
h1 that's meaningful we had hello react
over here maybe i'll say hello
everyone okay in my index.html i'm going
to get rid of this h1 so we're not
confusing this h1 with what i'm seeing
over here now reactdom.render the first
thing is what do i want to render to the
screen the second thing is where do i
want to render it well let's go to our
html and i'm going to create a div here
just a completely empty div and i'm
going to give it an id so that i can
select it we'll call it root because
this is going to be like the root of our
entire application i like to think of
this div as a container for the entire
website that we're going to build in
react and now that i have a place where
i can put my h1 here i'm going to select
it with a regular dom api
document.getelementbyid root
and surprise we've written some react
code i'm going to hit save
we'll see that it tells me hello
everyone in a single line of code i was
able to use react to insert something
that looks very much like an h1
obviously this is a little different
because we're still inside javascript
and i was able to put it right inside of
this real dom element in our index.html
now i have an entire lesson that's
dedicated to understanding exactly
what's going on here but in an effort to
get your hands on the code get a quick
win for you to see that you can write
react and it's not too scary i'm going
to give you a few seconds of silence
where you can pause the screencast and
study this line of code and then i'll be
erasing it and letting you type it again
from scratch in fact let me write that
down as a little challenge here
okay pause the screencast here spend
just a minute memorizing this line of
code do that now
and then i will add a little comment
with the next part
okay your time to shine rewrite the line
of code as best you can from memory you
don't have to put hello everyone or
hello react or whatever you even don't
have to use an h1 like i did you can put
whatever html you want in there so pause
the screencast now and work on that
because i pulled in that reacts dom
library in my cdn i have a global
variable called react dom and it has a
render method which allows us to render
something to the screen or kind of in
other words place something on the
screen and i don't know let's let's do a
paragraph this time just to switch it up
a tiny bit
say hi my name is bob
okay so that's the element that i want
to place inside of this div again this
div is a container for the actual
elements that i plan on putting on the
screen and the second parameter that i
need to include with reactdom.render is
you could think of it as a dom node that
i have to go select with
document.getelementbyid
or because i can also get dom nodes with
something like query selector that would
work just as well in this case i'd have
to put hash mark root because that's how
query selector works it's the id of root
just so this isn't confusing we'll just
keep it as get element by id for now but
just so you know either one should work
just fine so the first parameter is what
do i want to place on the screen and the
second one is where should i be placing
this i imagine under the hood what
render is doing is it's taking this dom
element that we are grabbing with
by id and it's running something similar
to dot append or dot append child to it
and what is it appending it's appending
this paragraph we're going to see that
it's a little more complicated than that
but that's a good way to kind of build a
mental model for yourself as to how this
is actually working so i haven't
refreshed the page yet which is why this
still says hello everyone i'm going to
hit save which will refresh my browser
and there we go hi my name is bob this
time it's a paragraph instead of a
header element and that's awesome we
have written react in a single line of
code you might have noticed that our
console is popping up with this error
you're using the in-browser babel
transformer be sure to pre-compile your
scripts for production a bunch of jargon
here that may not totally make sense to
you and that's fine that's a symptom of
us setting up react the easy way instead
of the correct way soon down the road
we'll be kind of shifting our setup here
and that warning will go away and
awesome okay because this is scrimba you
can always delete this if maybe you
weren't able to memorize that you can
try deleting it rewriting it again from
scratch practice with it i'm going to
ask you to do that a million times
throughout this course because the only
way to learn react is to write react as
much as you can now i have found it
really helpful for my own learning to
understand why the heck i even care
about react in the first place so in the
next couple screencasts we're going to
be talking about some of those really
awesome benefits that come with using
react as our library for building web
applications but as always if you want
to spend more time with this go ahead
and do that pause click into the editor
start typing what you want to type
practice it and when you're ready i will
see you in the next lesson
surprise if you know my teaching style i
wanted to include a practice in here
essentially you're just going to be
rewriting that same line of code that we
just wrote in the last lesson however
this time we'll extend it just a little
bit i want you to see if you can figure
out how to render an unordered list with
two or more list items inside last time
we just rendered a paragraph you can see
it's still kind of left over here if i
refresh that that'll disappear i've left
the entire setup here for you we're
still pulling in the script tags for
react react dom and babel so essentially
your main focus is just to rewrite that
same one liner of code but see if you
can figure out how to add a couple more
elements inside like having an unordered
list with some nested list items pause
here and try to work on that challenge
okay pulling in the react dom library
that gives us access to a render method
before we did a simple paragraph like
this and put some code inside however i
can put this as an unordered list
and then just actually stick some list
items inside of here
so it's going to look a little confusing
at first i'll clean it up in just a
minute we have
list item we'll just say thing one
and i'll do another list item
here
thing two
okay now i'm going to move this onto its
own line here this whole html thing
right there and the second parameter i
need to separate with a comma is where
to put this so i'm going to use
document.getelementbyid root and let's
cross our fingers see how this goes cool
okay hopefully that was some good
practice now let's keep moving forward
and learn a little bit more about why we
care about react
one more thing that was highly requested
from the first time i recorded this
react course was how can i set this up
on my local environment everything that
i'm doing will be done on scrimba.com so
that you can interact with the same code
that you see me writing however it's
also a good experience to run it locally
on your own computer and get a feel for
what it would be like to actually
develop react on your own computer again
our setup here is more of the easy way
than the right way but for now what you
can do is you can click the little gear
icon in the lower right of your scrimba
editor which will pop up a little menu
here and there's an option that says
download as zip that will download a zip
file containing the files that we're
working on here you can uncompress that
like you normally would any zip file and
open that up in any editor that you'd
like for example visual studio code on
your own machine now in order for that
to run i'm going to show you what that
looks like on visual studio code
inside a visual studio code which is
what you see in this screenshot there's
a menu icon for some extensions
and you'll need to search for an
extension called live server it's
created by ritwik day and you'll need
this installed to your vs code in order
to run the code that we have written in
react so you'll click the little install
button that's going to put an icon down
at the very bottom menu bar in visual
studio code that says go live
and all you need to do is click that go
live button which will open a web page
on a local server i think it's maybe
port 5000 that it runs and that should
launch your own react project on your
local machine as soon as you see me move
toward a different setup for react that
includes webpack and downloaded
dependencies from npm and so forth this
is no longer going to work in quite the
same way but for now for those that are
curious i thought i might just explain
how you can get this set up on your own
machine okay that's enough delaying
let's keep moving forward with the
course
let's spend a little bit of time
understanding why we even care to learn
react one of the main reasons that
people will talk about is how react
allows us to write composable code so
what exactly do i mean by composable
well an analogy that i came up with has
to do with sculpting if you think of the
statue of david for example this statue
was created originally from a single
giant block of marble that was then
sculpted down to the sculpture that we
know today so in the end what results is
one giant single piece that makes up
this piece of art now what if instead of
starting with one giant piece we instead
used a bunch of small pieces to put
together something that is greater these
are lego bricks that obviously are small
each in their own right that were put
together to create something large in
this example they all kind of work
together to accomplish a goal so to
speak the goal of looking like the
statue of david now this example is not
perfect because the original statue of
david obviously is more beautiful than
this replica made of lego bricks but
hopefully the concept makes sense let's
look at an example in actual web
development what i have here is copy and
pasted from the bootstrap website if
you're not familiar with bootstrap
that's really not important right now
but it's enough to know that these 30 or
40 lines of code copy and pasted from
the bootstrap website represent a
navigation bar that is pre-styled now in
the old days of web development a single
page on a website was usually a single
html page so if this is just the navbar
a lot of times those web pages would end
up being thousands and thousands of
lines of html code essentially making it
one giant sculpture well with modern
frameworks like react we can take code
like this and we can put it into our own
custom components and we can put those
components together to make something
that is larger but in our case our code
becomes a lot more maintainable and a
lot more flexible you can see i've given
these kind of silly names to show you
that these are not regular html elements
i can combine elements together that are
real html elements like you see here
into my own custom component called for
example my awesome navbar or my awesome
footer we're not quite ready to dive
into the syntax of react quite yet but
i'm going to give you a taste of it and
a chance to play with it before we move
on so let's see this in practice
over here you can see i have my react
dom.render and i'm rendering a custom
component called navbar and if i scroll
up you'll get a chance to see how i
created that navbar as a quick aside one
thing you might notice is that i'm using
class name everywhere instead of class
that's not a mistake that's just how you
have to assign classes in react we're
going to cover that later but for now
i'd like to give you a challenge that's
going to require you to deduce what i've
done here and try to replicate it for
yourself
so let me put that here
okay your challenge is to see the navbar
component that i have created and see if
you can deduce how to create your own
component called main content it can
return something really simple like a
single h1 element and afterwards i want
you to render it below the navbar you'll
have to figure out how to render it
below the navbar now i've changed this a
little bit for reasons that we'll talk
about soon but this line here 51 this is
where you're going to figure out how to
render your own custom component main
content so first build your custom
component looking at my example above to
try and figure out how to do that
and secondly render that component down
here in reactdom.render pause the
screencast and work on this challenge
well following the example above we see
that i created this component by
creating a function
and the name of the function is the name
of my component
so i will open up that function
and return the content that i want to
show up on my page above i created a
set of parentheses because i have many
elements that i'm trying to return i'll
just do that just to keep things
consistent for now
we'll create our h1 that says i'm
learning react and secondly i can take
my main content and i can render it by
making it look kind of like an html
element in this case it's a self-closing
one so i have main content as a single
tag here and if i hit save we'll see
that my h1 actually showed up on my page
and that's the concept of composability
it goes quite a bit deeper than this
we're going to see how we can make our
components much more composable and
reusable but for now let's move on to
another reason why people really love
react and we'll cover that in the next
lesson
another major reason people love react
is because it's something that we call
declarative so let's talk about
declarative to understand declarative
it's helpful to know that it's opposite
is something called imperative when a
program is declarative we can simply
tell it what should be done more
specifically it's like the computer
saying just tell me what to do and i'll
worry about all the nitty gritty details
on how to get it done it's opposite
imperative is when we need to tell the
program how it should be done like the
computer saying i need you to describe
to me every step along the way how to do
something and then i'll do it up until
now if you've mostly been just using
vanilla javascript anytime you needed to
create elements on the page you've been
doing it in an imperative way in fact
let's go look at what that has been like
i've commented out my react dom dot
render and i'm going to put a challenge
here for you
okay your challenge is to recreate this
above line of code where we are
rendering something to the screen using
vanilla javascript by creating and
appending an h1 to our div with the id
of root we have our div id of root
you'll need to select it and then append
a new element and i give you the
step-by-step instructions right here
one little caveat is i don't want you
using inner html because that kind of
breaks the analogy down a little bit
generally speaking this is actually just
a good way to practice the vanilla
javascript that you have been learning
so far so it's always good to give it
some practice i'll give you a couple
lines here pause the screencast and work
on this challenge
okay let's work on this so i'm going to
create an h1 and i'll use
document.createelement
and i'll make an h1 and then if i'm
giving it some text content i need to
use the text content property of this
dom node and set it equal to
i don't know maybe
this is an imperative way to program
then i need to give it a class name so
i'll use the class name property here
and set it equal to i think we said
header and finally i need to append it
to my div with the id of root so first i
need to say document get element by id
root and then use the append
property or method to append my h1
to the dom so when i hit save it should
show up this is an imperative way to
program perfect now this example is a
little bit on the nose because if you
were really just putting something
static that had nothing to do with user
interaction you probably would just go
to your html page and stick it right
inside the div here right but with react
we're building our entire page in
javascript and so doing something
imperatively this way where i have to
tell it step by step how to create the
element and then to add some text
content and then add a class name and
then append it to the dom that's going
to get old pretty fast especially even
with something mildly more complicated
than a single h1 like a very simple web
page like this as soon as we have more
than one element suddenly our four lines
of code will become probably dozens or
maybe even hundreds of lines of
javascript code just to create and
append all of these elements in the
correct order and in the correct way
and so that brings us back to the idea
of writing our code declaratively and
react allows us to do that in a really
simple way as we see back up top let me
comment this out and uncomment this we
essentially get to write our javascript
as if it were html we are relying on
react to figure out how to turn what we
have declaratively written as an h1 into
the javascript code that's needed to
append it to the dom in fact if i were
being strict and wanted to make this
more equivalent in order to add a class
name i can just add a class name as if
this were an html element again this is
class name instead of class for a good
reason which we'll talk about but that's
a pretty minor difference to be able to
do all of these lines of code in one
single section right here and that
difference is going to compound as we
get into more and more complicated uis
like we see here so at this point i
could probably continue talking about
different reasons that we're choosing to
use react and that it will be really
beneficial for you to learn react as you
see on my little list here it's a very
hierable skill and it's actively
maintained by really skilled people at
facebook however at this point i think
we're overdue to just jump into the
syntax get your hands on the keyboard
and start learning and practicing react
so when you're ready let's keep moving
forward
okay let's finally address this elephant
in the room what we're looking at here
why we have what looks like html stuffed
right inside our javascript well fairly
early on in the days of react the react
team created a syntax that's called jsx
jsx stands for javascript xml but that's
not terribly important for you to
memorize what's most important is to
think of it as sort of a flavor of
javascript that looks a lot like html
and with the introduction of jsx into
react it really made it so that react
was very declarative instead of
imperative
we can see up above what it took for us
to create an h1 give it some text
content and give it a class name in
regular vanilla javascript but with jsx
the benefit is that we can just write
what we're already used to writing with
html now there's a couple of small
differences for example instead of using
class i need to use class name so i
might say class name equals header for
example and there's a few other of these
but for the most part with jsx we can
just write the html that we're used to
writing at first it might be a little
bit confusing to write your html inside
of your javascript but i promise as you
start doing react it's really going to
start making sense you're going to learn
to love jsx now one thing that was
really helpful for me to understand as i
was learning was to see the difference
between what jsx is and what our regular
dom elements are so i'm going to do a
few things i'm going to uncomment these
lines of code here
and i'm also going to take this piece of
jsx
and
set it to a variable we'll call it
element then i can fix my
reactdom.render by just putting element
down here and this will work exactly the
same
but this allows us to console.log it so
let's console.log element and i'll hit
save so that this code will run i'll
open the console and we'll see the
differences here first of all on line
four we are console logging the dom
element that we created with
document.createelement
and that's what shows up in our console
as what looks like an html
element here so that's this line right
here however when we console.log our
element that we created with jsx what
actually got returned to us was this let
me copy this out
and we can see that this is just a
regular javascript object let me clean
it up just a little bit to make it even
more clear
so in the end what we get from jsx or
rather what react is creating with jsx
is actually just plain old javascript
objects and those objects describe the
dom element that we want react to put
onto the page for us and if we look
closely we can see some interesting
information here first of all we see
that
it has very similar properties like we
have class name where we're setting that
to header and down here we have props or
short for properties and we have class
name we also have something called
children and we can see that's actually
the text that we put inside of our h1
that's about all i care to touch on with
the
object nature of react elements but i
thought it would be helpful to kind of
kick us off understanding that jsx is
kind of like a function
that when it's run
returns us objects that react can
interpret and use to create actual
elements that get put on the screen for
us
i'm going to comment this out so we can
talk about one more thing clean up this
a little bit
and i'll go ahead and put this directly
back in line to my react dom.render move
these onto their own lines the last
thing that i wanted to touch on was that
with jsx we need to make sure that we
are only returning a single parent
element in other words i can't take this
one h1 and place say a paragraph
directly next to it
because in this case we're rendering or
attempting to render two sibling
elements that sit side by side in fact
if i try to run this you can see react
complains and i guess in this case it
says unknown error sometimes it will say
that you have to wrap the elements that
you're trying to render in some kind of
parent element now this doesn't mean
that i can't put two elements on my page
at any given time it just means that i
need to wrap them
in something like a div for example
so if i say a div that has an h1 and a
paragraph inside
now i am rendering just one parent
element and it doesn't really matter how
many children elements are included as
long as i have one parent element that
i'm rendering so i can hit save we'll
see that this is working just fine
now remember how i was able to save my
h1 as a variable well i can actually
save a whole collection of jsx for
example this div with the h1 and the
paragraph
as a variable
so let's say const page equals and then
i can paste in my elements here now to
me this looks a little bit crazy so
normally what i like to do is move my
elements my jsx onto their own lines as
if this were html but in that case i
need to go ahead and wrap everything in
parentheses
now take a second and think how is it
that i can then fix what i have down
here we can see we have a syntax error
how can i fix this so that when i
refresh the page this is still working
pause here and see if you can figure out
how to make this work again
well all of my jsx is being saved under
the variable of page so i should just be
able to put page here and hit refresh
and sure enough that's working just fine
hopefully some of you were kind of
curious to see what this looks like as a
javascript object if we console.log page
we can see that essentially we got what
we had last time but this time it's a
little more involved specifically in the
children property of our div we see that
there's other react elements in there
i'm not going to dive too deep into that
feel free to copy and paste what you see
in the console maybe clean it up a
little bit and analyze it but the point
is i can save a whole bunch of jsx into
a single variable and then use that
variable kind of like any other variable
and the key is that's because what i'm
getting back when i write my jsx is just
a javascript object okay i'm going to
clean this page up a little bit
and i'm going to comment out our page
because i'm going to give you a
challenge
okay i left our example of const page up
here just for reference but i did delete
our code that we had at the bottom which
actually enabled us to put something on
the screen and that's because i want you
to practice it again so your challenge
is to create a navigation bar using jsx
i've given you some instructions here on
what the content should actually be and
as i mentioned at the very end don't
worry about styling yet we're going to
cover styling soon but for now what
you're going to have is just going to
look like plain html that's unstyled so
pause the screencast here and see if you
can complete this challenge
okay before i worry about the react dom
dot render bit i'm going to create a new
variable we'll call it p actually let's
call it nav bar
and i'm going to use my parentheses so
that i can start my element on the next
line and like i mentioned we want to use
the
semantic nav element
and inside of there i'm going to have an
h1
let's call it
bob's bistro
maybe this is a restaurant okay and then
we have an unordered list
and hopefully while you were playing
with this you came to realize that it
doesn't matter how nested i get just
like in html i can nest this as deep as
i want
we'll create
three
list items
and it said pricing
about
and contact and i don't know maybe if
this is a restaurant i'll say menu
instead of pricing okay i've got my jsx
for my navbar setup and then the last
bit which was just meant to be something
repetitive that allows you to get some
muscle memory for this is to use
reactdom.render and the first parameter
is what do i want to render and that's
my navbar jsx
and the second thing is where do i want
to render it i'm going to do that by
selecting with get element by id
my div with the id of root that is over
in my index.html right there
okay i should hit save and sure enough
it's pretty ugly obviously we want to
style this we're going to get to that
soon i hope that challenge went well for
you if you struggled please don't keep
pushing forward go back re-watch this
lesson see if you can do this again from
scratch or maybe just try typing it 10
or 15 times if you need to also if you
get totally stuck don't forget that this
is a community you can reach out on
discord ask your question and you are
more than likely to get a really
friendly helpful response back when
you're feeling pretty good about this
let's keep moving forward
okay at this point it's probably time
for us to switch away from the easy way
of getting react set up in our project
to the more correct way now inside of
scrimba that means something different
than it means inside of your own local
environment scrimba has kind of some
magic that's happening under the hood
that's helping react just kind of work
in our project so i'm going to show you
a couple steps for how i do this in
scrimba you won't really have to worry
too much about that because even when
you're creating your own new scrim in
scrimba it'll just ask you what type of
scrim you want and you'll just tell it
that it's a react scrim and it'll set
everything up for you so what i need to
do is in my index.html i'm actually
going to remove all of my unpackaged.com
cdn's here
so i can get rid of these three lines
and i don't need this type text babel
anymore because i'm not pulling in babel
and instead over here on the left i'm
going to add the dependencies that i
need and i need react
and i need react dash dom
if you're a little bit more familiar
with developing in javascript you might
recognize that these dependencies are
similar to having a package.json where
you install these packages through npm
if pretty much everything i just said
doesn't make sense don't worry about it
at all i am going to talk about
different options for local setup later
if you absolutely need to follow along
in your local environment instead of
here on scrimba.com you can continue to
use the cdn way that we were just using
like this but otherwise i just recommend
doing things here inside of scrimba our
main focus is not going to be how to set
up react but rather how to write react
so i will take those back out and now
that i have taken those cdns out it
means that i no longer have global
variables added to my window like react
dom so if i try to save this we're going
to see i have an unexpected token angle
bracket
and that's because well it doesn't know
what react is at all what i need to do
now is actually import react
from react
this might not seem like it's doing
anything because i'm actually not
referencing react anywhere here i've got
react dom but that's something different
however react is where the jsx syntax is
defined and so i need to import react in
order for this to work at all now the
astute among you might be familiar with
the fact that with react version 17 i
technically don't need to import react
however currently at the time of this
recording scrimba is not yet set up to
support the fact that react version 17
and above no longer requires you to
import react in order for jsx to work so
anyway throughout the duration of this
course i will be using import react from
react and that's because well i need to
in this environment currently let's hit
save again and see what we run into next
and this says cannot use import
statement outside of a module and oh you
know what i think that has to do with
another sort of magic piece that is
happening under the hood with scrimba so
i'm going to add this.pack that's not
something you'll need to do in the real
world so this should be yep react dom is
not defined that's the error i expected
to see and that's because whenever we're
using react dom i will also need to
import
react dom from react
dom
and now fingers crossed i should get
something that works again okay there we
go we're back on the screen and
everything is set up a little more
similar to how you normally would see a
react project setup don't be overly
concerned with all of these
implementation details however this is
how i'm going to be setting up my
projects from here on
and at this point we actually have
enough knowledge for us to start working
on this section's project which is a
static html page in react however before
we jump into that i want to exercise
your brain with a little thought
experiment and we are going to do that
in the next screencast
i'd like to do a quick thought
experiment with you and that is to
figure out why we're using react dot
render instead of just using the dom
append method that you've probably used
before in javascript i've written the
first line for you and that's to import
react from react that will just allow
you to write some jsx your challenge as
you can see in this little four step
process here is to create just a really
simple sample page in jsx it has to be
greater than or equal to four elements
just to get your fingers working a
little bit and i want you to save that
jsx to a variable remember that that
variable needs to be one parent element
with some children elements nested
inside of it in other words we can't
just have two sibling elements saved in
a variable in jsx then i want you to
select the div with the id of root using
whatever selector you want to use and
then use dot append to append your jsx
if you need to do a quick google search
for how to use dota pen that's totally
fine and then before you run your code i
want you to see if you can guess what's
going to show up in the browser before
you run the code and then run your code
and see if you can explain what does
show up in the browser pause here and
play around with this a bit
okay well let's create our jsx we'll say
const page equals and i'll open my
parentheses so i can write my jsx on its
own line
and we'll start with a div
just to surround everything
and i don't know let's say i'm making a
page about
why i
love react we'll say this is my awesome
website in react
and then maybe in h3 that says
here are the reasons i love react
and we'll use an ordered list
it's not terribly important what you
actually put in here
i'll just use some of the reasons that
i've been talking about it's composable
it's declarative
it's a very hirable skill to have
let's see i need to get rid of this
and
it's very actively maintained by some
very skilled people
again the jsx you chose to put in here
is not terribly important so we'll use
document.getelementbyid
root and then
use the dom
nodes append method
to append our page
and we'll see what shows up here now of
course i know what's going to show up so
i'm just going to run the code and we
see that we get object object this
object object is sort of a string
representation of a regular javascript
object something i can do to actually
make that object appear is to stringify
it using json so i can actually say
json.stringify
and we will stringify that object so
that it puts json on the page i'll hit
save
and look at that we get a javascript
object
now
step four see if you can explain why
this actually shows up in the browser
well kind of the whole purpose of this
thought experiment was to remind you
that jsx returns plain javascript
objects at this point in time it has
nothing to do with the dom it's not
recognized by the browser as anything
important dealing with the dom it's only
when we try to render it using react
dom.render that react can take these
javascript objects and actually turn
them into real dom elements that the
browser can interpret as things like
first level headers or ordered lists
so let's go ahead for the sake of
practice and fix this i'm going to
update our challenge here
okay simply put your challenges to fix
our code and don't forget we're not
using those cdns in our html anymore
which is what used to give us a global
variable called react dom so you'll have
to see if you can remember how we get
access to react dom pause the screencast
here and try to fix our code
in order to use react's dom i will need
to import it and we'll import it from
the react dom package
then instead of selecting my div with
the id of root actually i'm going to
need that anyway so i will leave that
code there i'll say react dom
dot
render the thing i want to render is my
page so we'll put page and the where i
want to render it is
inside of that div with the id of root
i'm going to comment this out so it
doesn't break it we'll hit save and
there we go awesome so simply put react
dom's job or the react dom.render
methods job is to take react elements
and interpret them in a way that turns
them into real dom elements that the
browser can understand
okay with that understanding it's only a
small jump to work on our section
project which is to build a static page
in react we're going to start the first
steps of that in the next screencast
okay we're finally at our first
challenge i'm really excited to start
working on this i've included a google
slide of what you're aiming for with
this challenge notice there's really no
styling being applied here at all it's
just bare html so if we go look at the
challenge essentially you are starting
completely from scratch and your job is
to build the html for our section
project as you see it here we'll be
adding just a little bit of styling to
it later after we learn how to do that
and i've included a couple hints here
for simplicity i've imported the react
logo file directly into our file
explorer here which means that you can
reference it in your image element that
you create with source equals and then
using a dot slash react dash logo dot
png i also have a hint here about how to
set the width attribute just remember
that jsx is almost identical to html and
in fact for what you're working on here
you really shouldn't see any difference
between the jsx that you'll write and
what you would normally write in html
don't forget that we are no longer using
our cdns so you'll have to remember how
to bring in react react dom and so forth
that's all the hints i'm going to give
you so pause the screencast here and
work on this challenge
well first things first let's import
react from react and import react
dom from react-dom
we can't really do anything until we've
done that
then i'm going to save a variable called
page and as a heads up
this isn't actually going to be a very
common way for us to deal with jsx we're
going to see very soon how we can do
this in a more conventional way for the
sake of learning though i think this is
a good way for us to start just to do a
bit of a sanity check i'm going to just
throw an h1 in here
it says testing and then do my last step
which is reactdom.render
and we want to render our page
and we want to put it at the
div with the id of root
let's see if that's working okay cool we
have testing showing up that means that
everything else is set up correctly
okay so let's start building our page
here i'm going to surround everything in
a div
just because i can only have one element
here rather one parent element here
instead of any sibling elements and the
first thing i'll put in is an image and
just like in html i can provide an image
source and like i mentioned up in the
hints i'm going to have
react dash
logo.png
the dot slash just means look in the
same folder for a file called
reactlogo.png
now if i refresh this i'm going to get a
pretty large image here so just like in
html i can set the width to be something
specific like 40 pixels
and that looks a little more manageable
a little less crazy not taking up my
whole screen next i've got something
that looks kind of like an h1 that says
fun facts about react so we will add
that in there
and awesome now because my h1 is a block
element it has floated below my image
even though my image is technically an
inline element
and that's kind of to be expected or
rather that's what we're aiming for and
then it looks like the last thing is an
unordered list with these five list
items so i'll go ahead and add that
unordered list
do some list items
i'm going to hold shift option down to
copy these lines
and then just start typing in some of
these facts
okay and yeah these are some pretty
interesting facts about react i'll hit
save and awesome it looks like we
essentially got to where we wanted to
get to with our goal here i'll go ahead
and clean up some of my comments up here
from the challenge and great work
hopefully you were able to follow along
with that now like i mentioned saving
all of our jsx to a single variable like
this actually isn't really that common
nor is it convenient at all so what
we're going to start covering is a much
more common way and that is by creating
custom components before we jump into
that i want to give you a quick quiz
over the topics that we've talked about
so far and we will do that in the next
screencast
before jumping right into the next topic
i thought it would be smart to have a
quick little pop quiz on some of the
topics that we've covered up to this
point because this is scrimba you can
just click into this quiz.md file and
answer the questions here so pause the
screencast and work on this quiz
why do we need to import react from
react in our files well it's because the
jsx syntax is defined in react and if we
were to remove react we would see that
it's telling us react is not defined
even though we're not using react in our
code the jsx here sort of demands that
react be a part of our code base so i
will go type that over here
react is what defines jsx so in order to
use jsx we need to import react if i
were to console log the page in our
index.js file what would show up
hopefully you actually attempted to
answer this question before just going
ahead and console logging it before i
hit save i know that page is a bunch of
jsx which in reality just returns some
javascript objects so when i console.log
page i should just see a javascript
object here and sure enough there it is
if you look closely at that object
you'll see a children property and that
children property has more react
elements nested inside well that's
because we have our react element here
with children that are more
react elements
so over here we can say
a javascript
object
these are react elements
that describe
what react
should eventually add to the real dom
for us
okay number three what is wrong with
this code hopefully you noticed that our
jsx here is two sibling elements and
remembered
that we actually need
all of our jsx to be nested under a
single parent element
as a quick sneak peek in the future you
may learn that you can use something
that looks like an empty tag like this
in order to wrap your jsx in something
that doesn't actually create another
parent element these are called
fragments but that's more a little piece
of trivia we're not going to concern
ourselves too much with that in this
course
next is number four what does it mean
for something to be declarative instead
of imperative
the way we described it before was to
say that declarative programming meant i
could tell the program what to
accomplish and it would know how to
accomplish the specific step-by-step
details whereas imperative meant i still
needed to tell the computer step by step
how to do everything an example i like
to think of this is to imagine myself
asking a friend to make a peanut butter
and jelly sandwich for me if i were
doing that declaratively i could simply
say could you make me a peanut butter
and jelly sandwich and i would assume
that they knew how to take care of the
individual steps to do so if i were
being imperative on the other hand i
would have to tell them to grab a slice
of bread with their fingers and place
that slice of bread gently on a plate
then to grab a knife from the drawer and
to put the knife into a jar of peanut
butter and so forth there certainly are
times when something imperative is
warranted however generally speaking
writing code declaratively is a much
better developer experience and honestly
usually leads to fewer bugs in the end
so declarative
means i can tell the computer
what to do
and expect it to handle the details
imperative
means i
need to tell it how
to do each step
and lastly what does it mean for
something to be composable well that
just means that i can create small
pieces that i put together to make a
greater whole in terms of web
development it means i can take pieces
of my ui my user interface and put them
into their own components and then piece
those components together to build my
page so what does it mean for something
to be composable means that
we
have small pieces that we can put
together
to make something
larger
and i'll even say greater
than the individual pieces
this is a pretty broad definition of
composable because the idea and concept
of composability extends throughout all
of computer programming not just web
development and especially not just
react but i think we've gotten the point
across i'm really excited to keep moving
forward we are now going to jump into
sort of the baseline level of react and
start learning how to create our own
components and it's just going to get
more and more exciting from there so
strap yourselves in and let's keep
moving forward
when we talked about composability being
one of the major benefits of react we
talked about the possibility in react to
create our own custom components
what we currently have going on is we're
saving our jsx elements here or react
elements in a variable and then
rendering that variable directly with
reactdom.render
and although this has been working for
us so far it doesn't allow us a lot of
flexibility when it comes to creating
our own components in react and even
further it's also pretty obvious we
wouldn't want to take all of our markup
and stuff it directly into
reactdom.render
even though i think technically this
might work just fine actually i'm
curious let's give this a shot i'll
comment this out
okay so everything is technically still
working but we run into the same issue
as we used to in kind of the old days of
creating html code where if we're trying
to stuff everything into one place
not only do the elements not become
reusable but it becomes really difficult
to maintain as a developer so creating
our variable up here got us one step
closer but it's still not quite good
enough instead what we are going to
start learning about is creating our own
custom components now i give you a taste
of this early on in the course but we're
going to actually learn it the real way
now
in programming the concept of a function
is one that allows us to write some code
that we can then execute over and over
and over again just by calling that
function and react adopts the same
concept of having a function that allows
us to create user interface or create
elements over and over and over again if
we wanted to
knowing how functions work it's really
tempting to say okay well i'm going to
create a function and let's give it a
temporary name for just a second
and we might say well i have a function
and i want it to return my ui my
elements here anytime that function gets
called
so i might try something like this let
me get rid of page here and then instead
of page
we might say well let's call our
temporary name function and that is
going to return the react elements that
we asked it to and therefore we have a
function that we can reuse well let's
see what happens
look at that it actually worked and what
we have here is basically 90 of the way
into creating our own custom components
a function like this that returns react
elements is considered in react a
component however there's a couple of
conventions that we need to follow for
everything to work correctly all the
time the first one is we need to use
pascal case instead of camelcase for our
component names all that means is i need
to capitalize the first letter of my
component and secondly instead of
calling this function with parentheses
like we might be used to we actually
need to wrap it in angle brackets
similar to an html element and i still
need to change this to a capital letter
there and that's the only changes we
need to make from a regular javascript
function that you have probably written
hundreds of by now and a react component
that uses the same concept of functions
to create reusable user interface pieces
you'll see if i hit save everything is
still working as we would expect
okay maybe you can feel it it's time for
a practice i'm actually going to erase
everything because you are going to
write everything again from scratch
first i'll write out the challenge for
you
okay i've erased our code and saved it
so that our page went away this
challenge is going to be given to you in
two parts the first part is to create an
ordered list that enumerates the reasons
why you're excited to be learning react
don't spend too much time trying to come
up with a huge list just put a few
things in an ordered list and then i
want you to render your list to the page
this is going to require you to remember
all of the steps that we've learned so
far on the basics of setting up a react
app so pause the screencast and work on
part one of this challenge
to get started we need to import react
from react i need to spell react
correctly there and we'll import react
dom from react-dom
we'll go ahead and use react dom to
render
let's start with just some inline
jsx here we'll say
it's working
and i need to select my
root element
as the place to put this h1
hit save as a sanity check and we know
it's working awesome now the meet we are
going to create our own custom page
component by using a function called
page using a capital letter to begin and
this function is simply going to return
some ui or in other words some jsx that
we can put in the page
just as another little sanity check i'm
just going to remove the h1 here and put
it inside my page component
and then render
my page component as we've learned
and i refresh and everything is still
working and just to make sure i'll just
make a change i'll say it's still
working
okay so now the next part we are going
to turn this into an unordered no an
ordered list
and we'll just put a few
list items in here and let's see these
are reasons that we're excited to be
learning react maybe for one it's a
popular library
so
i'll be able to fit in with
the cool kids
this probably has a pretty loose
definition for what the cool kids are
but that's okay
okay we'll
put a second item here
and just so you can see everything i'm
gonna move this onto its own line there
we'll say i'm
more likely to get a job as a developer
if i know react
and hopefully you have some other good
reasons i'm gonna leave it at that for
now just for the sake of learning i'll
go ahead and refresh and there we go
we've got our two pretty ugly unstyled
elements that we have on the page but it
seems to be working okay nice work on
part one of the challenge in part two of
the challenge which will be in the next
screencast we're going to add a little
bit more to our simple page here however
before moving on if any part of this was
still confusing for you i really
encourage you to go back try to re-watch
some of these videos you could even
start from the beginning maybe you'll
have some additional context that will
help in your understanding and as always
reach out to the scrimba community on
discord if you have any questions people
are always happy to answer but don't
just plow forward if you're still
feeling confused do some research
re-watch some of the videos make sure
you're doing all of the challenges and
then when you're ready let's go forward
and we'll work on part two
the next part of our challenge is to add
some more elements to our page here
first i want you to add a header element
with a nested nav element inside and
then inside the nav you'll have a nested
image element with the source that i've
mentioned here and some other notes that
you should read through i also want you
to add an h1 element that will go below
the header element but above the ordered
list and at the very bottom underneath
the ordered list i want you to add a
footer element with some text that i
have here make sure to read through the
whole challenge there so you get a
better idea of what you need to be
working on and as always pause the
screencast here and work on this
challenge
one of the biggest tricks in this
challenge is to make sure that you don't
just try to add a header hopefully that
didn't cause too many headaches for
anyone but the biggest problem with this
is that again i'm trying to create two
sibling jsx elements here
one with the header and one with the
ordered list inside of a component i
just can't do that i have to have one
parent component so i could either use
those fragment tags that i briefly
mentioned earlier like this
or a lot of times you'll see people just
wrap it in a div like this
now that i've done that everything is
working again the way i'd expect inside
of my header
i'm going to include a nav element
nav is just basically an html5 semantic
element that is basically the same thing
as a div except it's better for screen
readers and assistive technologies
inside of my nav i'm going to have an
image element
and that one needs to have a source that
i included up here so i'll just copy
this
and make sure i get that quotation mark
there
get rid of that extra space
and let's just save this and see how
things are looking okay and my react
logo is huge so i'm going to give it a
width of 40 pixels like i've done before
okay that's more manageable next we need
to add an h1 with some text describing
the page like reasons why i'm excited to
learn react we'll just copy that
let's see that'll go underneath the
header
and we'll put an h1 there
and i'll just paste that text in right
there
refresh it and okay that's starting to
look good
then at the very bottom so this is
above this ending div because i still
need it to be a part of my page
component but below my ordered list i'm
going to add a footer element
and inside the footer we need to have
this text here
but we'll customize it to be relevant
for me so currently it's 2021
this is got semantic problems because i
have those elements there and i'm going
to call this zarol development because
zero is my last name all rights reserved
real official this is not going to be
stolen by anyone for sure now that i
have this footer here and let's go ahead
and refresh this sometimes people will
put this inside of a small tag i'm kind
of just curious to see what that looks
like
i need to end this correctly and yeah i
guess that looks a little better we'll
leave it like that okay nice work now
some of you may have been wondering well
why am i just building everything as
this monolithic page component i thought
the whole reason that we were creating
our own custom components is because
then i can compose them together instead
of just shoving everything into this one
component and you would be right so in
the next lesson we are going to learn
how to compose these elements together
learning the concept of parent and child
components and so forth before we do
that though i want to make sure that
you've been awake and that you're
following along we're gonna have a quick
quiz so that is coming up next
okay it's quiz time again read through
the questions in the quiz actually click
into the editor type down your answers
and if you find yourself not knowing the
answer to one of these don't just kind
of plow ahead but instead actually do
some research see if you can figure out
on your own with google and whatever
other resources you have available to
you what the answer to the quiz question
is before just moving on so pause now
answer the questions to the quiz and
then we'll go through them together
all right number one what is a react
component well basically put a react
component is simply a function that
returns
react elements well what exactly are
react elements react elements are the
objects that get created when we return
jsx so although this looks very much
like html remember this is jsx which is
a special syntax of react and under the
hood it's returning a regular javascript
object those objects are eventually
turned into real dom elements that
people can see on the screen so
sometimes you'll hear people refer to
this as ui or user interface and that
just means that it's what the user can
actually see on the screen and just like
any other javascript function a
component can be reused over and over
here i'm creating a page component but i
can run my page function so to speak or
in other words create an instance of my
page component by just rendering page
again
okay let's go to number two what is
wrong with the following code it's a
really small difference but it's an
important one any components that you
create need to begin with a capital
letter this is called pascal case where
it's essentially camel case but where
the first letter is also capitalized
basically anytime you might want to have
i guess you could say different words in
your component name like my component
all you do is capitalize the first
letter of the next word this would of
course be instead of putting some kind
of space in between there like in a
regular sentence and then finally what's
wrong with the code in number three
hopefully this one wasn't too difficult
to find but if you look way down here
instead of calling our function like you
might normally be used to by adding
parentheses at the end with function
components in react you instead surround
these with the angle brackets as if it
were a regular html tag and in react
this is the correct way to i guess you
could say call your component or create
an instance of your component
okay short and sweet nice job on that
quiz hopefully you were able to follow
along next we're going to move forward
and see how we can do a better job of
composing our components together
as we've mentioned it's not ideal to be
taking our entire markup and stuffing it
into one component like we're doing here
so let's learn through practice the
concept of creating a parent and child
component
we're going to start this off by having
you do a mini challenge so let me type
out that challenge here
okay your little mini challenge is to
take the header element from our page
and to put it into its own component
that's called header technically
speaking i'm not necessarily asking you
to then render the header inside the
page but if you want a little extra
credit challenge you can render that
header component that you just made
inside of the page here pause now and
work on this mini challenge
okay just like it says we are going to
create a separate header
component here and we're doing this
outside of page because they're
different components
and basically i can just cut out this
whole header section
and return it from my header component
and that's really all the mini challenge
was asking you to do now if you didn't
try to do the little extra credit i gave
you and render the header inside here i
want you to think for a second what
might that look like
well just like we are creating our page
component down here or rather we're
creating an instance of our page
component down here
i can create an instance of my header
component by just typing it out like
this
as if it were an html element amongst my
other code
and here we see the concept of
composability in practice i've set aside
some of my ui to be managed by a single
header component and then anytime i want
to essentially insert these elements
into my page i can create an instance of
my header component just like this
now in a web page that's this small it's
really not that necessary to do this but
i'm sure you can imagine if this were a
much larger application
especially one that had pieces that had
a lot of user interaction and so forth
it becomes really really beneficial to
move these things into their own
separate components
okay so that leads us to the next part
of this challenge which i will type out
now
essentially i want you to do the same
thing but now with the footer as its own
component and the rest of the content as
its own component pause now and work on
this challenge
okay just like before we'll create a new
footer
function or component here
and it's going to return
the footer content i'll just cut that
out of there
put it right here
and down here in its place we will
render the footer component
okay and then we'll do the same thing
for the
main
content component
i'll take everything here including the
h1
and there's a little trick here because
if you tried to just paste that in
you'll notice that this is two sibling
elements which again we can't just
render side by side we need a parent
element to surround them
so i will put this div down there
indent there
and we will render an instance of our
main content component
now i should be able to refresh the page
and essentially have the exact same
thing
of course now that i've wrapped this in
a div very technically speaking these
elements are now children of the div and
the div exists right here on this level
for my purposes now this div is not
harming anything it's not changing my
styling or anything
so i'm not terribly worried about it
so hopefully you can understand now the
idea or the naming of parent child
components we have a parent component
which is our page component
and just by virtue of it rendering other
components these other components become
by name children components
and just like html this can go deeper
and deeper down the rabbit hole i could
have main content rendering another
component that we have also made
and then relative to main content that
other component would be a child
component and main content would be the
parent component this really is no
different than in our html how you can
have different levels of parent child
and even grandchild or whatever you want
to call it nice work on this challenge
you can see that we are now composing
our page together of other components
now we're pretty overdue in learning the
ability to add some styling to our page
so that's what we're going to work on
next
we're going to start off this lesson
with a sort of mini challenge our goal
is to add a navigation bar to our little
site here and navigation items like this
are usually handled with something like
an unordered list with list items so
that's your challenge underneath our
image here your challenge is to add an
unordered list with three list items for
pricing about and contact in the end
this will essentially be like adding
some html to your page so this should be
pretty quick pause the screencast and
work on this challenge
simply enough we can add an unordered
list
with our three list items
for
pricing
about
and contact
let's hit save and see where we are okay
pretty ugly but we're going to style
this now fortunately styling something
in react is as simple as adding classes
just like you would in regular html the
only difference you need to know about
is that instead of using class equals
we're going to use class name equals and
that's because under the hood if you
remember react is taking these jsx
elements and turning them into native
dom elements and just like when we were
creating things in vanilla javascript we
would say something like const unordered
list equals document dot create element
with unordered list as the type
and then we would say ul dot class name
equals something if we wanted to set the
class name
so in the end that's why we're using
class name instead of class in react
and so i will set the class name here to
maybe nav dash items
hit save and then in our style.css i can
add
nav items and maybe first let's take the
list style off so we'll say list style
of none and sure enough our bullets go
away and that brings us to the next part
of this challenge
using flexbox i want you to line up the
nav items horizontally so that they sit
next to each other like this and then
also using flexbox i want you to line up
the unordered list with your newly
horizontal list items to be in line with
our logo so that everything is nice and
aligned just like we have in this image
in doing so i want you only to use css
classes i don't want you to select any
bare elements like the whole nav or
anything like that mostly just so we can
get some practice typing out class name
pause the screencast and work on this
part of the challenge
well let's piggyback off our nav items
class which we already have i should
just be able to change the display to
flex and sure enough that gives me all
of my items in a row now let's put our
list item in line with our logo image
here and then we'll worry about some
spacing between these items
back in my code i'm going to
probably give my nav a class name of nav
of course i could have just selected the
whole nav element but like i mentioned
we're here to practice class names so
i'll make a class name of nav
and we'll select our nav let me hit
refresh over here so that the styles
will apply immediately
and i'll give this a display of flex
awesome our elements are in a line now
because my nav only has two elements the
image as the first element and the
unordered list as the second element i
guess i should say to direct children i
can just use
justify content
space between to push that pricing about
and contact items to the far right
it also looks like our logo got a bit
stretched that just kind of happens in
flex containers so i'll say align item
center and that should fix my aspect
ratios of the image
and then i'll go ahead and add a little
bit of space between my list items there
i know i mentioned using classes but in
the case of list items i usually prefer
to
select the unordered list by its class
and then just select all the list items
that way i don't have to go in and add a
class name to every single one of my
list items
let's just give those a padding of maybe
10 pixels okay that's looking pretty
good now my image is looking a little
bit small to me i want to make it bigger
but oh yeah we added this width
attribute but now that we know how to
style with classes let's have sort of an
impromptu third part of this challenge
okay your task is to change the image
styling to happen in the css instead of
right here in line and of course for
practice let's add a new class to the
image just so you can style it that way
pause the screencast and work on this
part of the challenge
simply enough we can take our width out
which is going to make our image pretty
huge if i refresh but we'll give it a
class name let's call it nav dash logo
and then we will select our nav logo and
let's give it our width of 40 pixels
again
i have to hit refresh over here
okay we're back where we were actually
this logo is looking a little small let
me try 60 pixels yeah i think i like
that size better at this point i think
it's a perfect opportunity for you to
continue practicing styling this page
obviously this page is really small in
its scope and so before we just push
forward i would like you to spend at
least a few minutes styling up this page
making it look a little bit nicer add
your own flair to it in fact i actually
did that and put maybe five minutes of
styling into it which obviously shows
it's not going to win any design awards
but i did change the font to use a
google font i added this little box
shadow under our nav bar i moved the
footer down to the actual footer section
of our page the bottom of our page and
added some really basic styles to it so
this is a great opportunity not only for
you to flex your css skills and get your
hands on the keyboard and do some
practice but also to interact with the
scrimba community especially on discord
once you've styled something up that
looks well pretty much anything's going
to look better than this once you have
some kind of style added take a
screenshot and share it in discord as
you make changes to your code here in
scrimba it will create a note that you
can save and you can even share that on
twitter you can share the link to that
and discord whatever it takes for you to
get involved with the scrimma community
once you've had a chance to apply some
of your own creativity to this little
page the next thing we're going to do is
clean up our code here where right now
we have everything kind of stuffed into
our index.js file and we're going to
learn how we can move these components
into their own folders and clean up our
code a bit
there are practically innumerable ways
to organize your projects and so i'm
hoping to in this screencast just teach
you some of the principles and as we go
through the course you may see different
methods that i use and of course as you
look at other people's code you'll see
the ways that they use as well for
organizing their code now what we have
here is a very small site for react
there's hardly anything here i barely
have 50 lines of code to make this page
however anything substantial that you
have will end up being hundreds more
likely thousands or even tens of
thousands of lines of code in total so
it's really important to have an
organization system that makes sense to
you to your group and something that you
agree upon in the beginning and stick to
as you continue to develop so i'm going
to show you with separating one of these
components into its own file and then
i'm going to give you a challenge to do
the same for the others so what i'll do
is work on the header and we're going to
move header into its own file so i'm
going to create a new file in my
explorer up here called header js
a convention that i personally like to
stick to is that any file i create that
will essentially house a react component
will start with a capital letter the
same as the component's name itself now
i'm going to copy or actually cut this
entire component out
and over in header js i'm going to paste
it
now there's a couple things i need to
change here i want you to pause the
screencast and see if you can think of
two things that i need to change in this
file in order for me to then be able to
import it into this file so that it's
working the way that it was before
so take a good look at this pause the
screencast see if you can figure that
out
well remember in order for the program
to make any sense of jsx i always need
to import
react from react
even though we're not explicitly using
capital r e a c t anywhere here in my
code for jsx to work i will need to
import react from react again this is
something that has recently changed if
you're working in an environment that is
actively using the updated react 17 then
you may not have to do this
the other thing is currently this
component is completely stuck inside of
this file i'm not sending it outside of
this file anywhere
and so i need to
export it
and oftentimes if this is the only
component that i'll have i choose to
export default the component so i'll say
export default header alternatively i
could save myself a little bit of
lines of code here and just put export
default function header right up at the
top and then i don't have to create a
separate line down here that does it
separately personally i kind of
oscillate between these two so you can
just choose whichever one you think you
prefer the most and stick with that
convention
if you're feeling a little bit rusty on
export import export default and so
forth you may want to spend some time
researching import and export in es6
because we will be using it quite a bit
in this react course
now that i have exported my header
component it means that over in my index
js i can import it
and i'll say import header from
and then i have to use dot slash capital
h header
and i could say js but that's the
default extension for imports so i don't
need to specify.js
in this case dot slash is a way to
indicate that i'm talking about a file
in my own project here not a package
that's in my dependencies like react and
react dom
and i have to make sure that i spell
this the exact same as my file name not
necessarily the name of the component i
could have chosen to call this head
like that and i still would have to say
import header from dot slash header or
in this case i could say import whatever
because i'm doing an export default
if that's confusing don't worry too much
about it i prefer to keep the names all
the same so that i don't run into any
confusion there
okay i'll put an extra line here what's
nice about this is now my code is sort
of sequestered into the header.js file
which means that if i want to change the
header
i can logically come to my header.js
file to make changes to my header
and i don't need to change how it's
rendered down here because when i import
it i'm importing everything that i have
in my header.js file just like it was
when it was declared here in the
index.js file okay let's get some
practice let me type out your challenge
simple enough just move the footer
component and the main content component
into their own files and then of course
do what you need to do to make it so
that our site doesn't break down pause
the screencast and work on this
challenge
okay let's do this i'm just going to cut
my footer out
create a new file called capitalf
footer.js
paste my code
in and we'll import
react from react so that our jsx works
and then i'll export default
my footer function my footer component
and make sure that i
import it here
say import footer from footer and just
by importing it now my footer should
just be working the same way as it was
hit refresh and everything is working
awesome
we'll do the same thing for main content
and i can clean up some of these extra
lines
create a new component or file called
main content.js
paste it in
export default
import react from react
and
of course we haven't yet imported it so
we will import it
main content
hit save and we're back up and running
we can remove this challenge and all of
a sudden we're down to 17 lines of code
we're importing these components from
other files and that way we have a much
better organization on our app here
again like i said there's a million
different ways to organize your code
it's also not uncommon for people to
even take this component that's sort of
organizing our other components and put
it in its own file a lot of times
instead of calling it page they'll call
it app that's actually the convention i
tend to use so maybe i'll go ahead and
just change this to app while i'm at it
but because of the limited size of this
project i'm not terribly concerned about
moving this component into its own file
and then also importing all of those
other components into that separate file
it just feels like
maybe over engineering it for such a
small project okay awesome work
hopefully this has been helpful we're
going to be using organization like this
throughout the rest of this course so
again if you're feeling confused about
how we're exporting things or importing
them then you may want to spend some
time researching export and import in
es6 just to become a little more
familiar with it or another great way to
do that would be to just play with this
code see if you can delete these lines
delete the export default line and just
try to recreate it see if you can get it
to work again when you feel comfortable
with everything we've covered so far
let's keep moving forward
earlier in the course we saw sort of the
quick and easy way to get a local
version of react up and running using
some cdn links and an in browser babel
transpiler to get everything working you
see since react uses a syntax that isn't
normally understood by the browser there
needs to be some kind of tool to
translate this weird-looking javascript
like jsx into something that the browser
can actually make sense of like regular
old javascript however that in browser
babel transpiler that we were using is
not really a good long-term solution
which is why we saw that warning that
says well basically you should do this
in a different way if you're going to be
pushing it up to production so instead
what you normally need to do is set up a
whole bundler system using something
like webpack i've linked to the webpack
homepage if you want to go visit it
there and you would teach your webpack
configuration how to use babel the
transpiler or compiler so that
essentially it would take your react
code and transpile it or compile it down
to something that is readable by
browsers with regular javascript
just to be totally clear babel and
webpack are not specific to react but in
order for react to work on most web
browsers you would normally have to use
babel and webpack to translate it into
something that a browser would make
sense of and the truth is unless you've
already dealt with webpack a bunch
before it's honestly a bit of a high bar
for beginners to clear when they're just
learning web development so to help
significantly reduce that overhead in
getting started with react the react
team created a package called create
react app which does all of the heavy
lifting for you and it even hides a
bunch of that implementation detail of
webpack from you in the code
so in the end it really just makes
setting up a new react app on your local
machine really simple so let's take a
look at the process of using create
react app to create a new react app on
your local machine before you can jump
into create react app you have to make
sure that you have nodejs and npm
installed on your machine to see if you
have these installed you can open up
your terminal and type node space dash v
that's a flag to check the version of
node if it spits out any number that
means that you do have node installed
and if you do have node installed then
you also more than likely have npm
installed as well but for good measure
you might as well run npm space dash v
and again if it displays a version
number that means you do have npm
installed
now the next few slides are going to
give a very high level overview of how
to install node in npm so if you already
have node and npm you can sort of tune
out the next couple minutes or skip
ahead and honestly there's a lot of help
already out there on how to install
node.js i would just recommend going to
youtube and searching install node.js
but specifically install nodejs with
something called nvm
so i would recommend using nvm which is
the node version manager its purpose is
just to make switching and installing
different node versions extraordinarily
easy but it does mean that you have to
install another package if you're on a
mac or linux machine you can use nvm
i've included a link to their github
repository here or if you're on windows
you can click here to go to a package
called nvm-windows but again i would
just default to following some kind of
install node.js with nvm tutorial that
you find on youtube
okay so now you have nvm installed the
next step is to open your terminal again
and this time type nvm space install
space dash dash lts now this command is
specific to the nvm for the mac or linux
i think it might be slightly different
for nvm-windows i think that might just
be nvm install lts with no dash dash but
you'll have to check the documentation
and follow the instructions in that
youtube video to be sure
then once that finishes installing we
come full circle and you should be able
to double check your node version and
your npm version the same way we saw
before and again by the time you're
watching this it very well may not be
these versions it might be a newer
version than this
now with node and npm installed we're
ready to actually use create react app
on the create react app website you can
see this getting started section the
main thing we care about are these
commands down here just to make things
even more confusing there's another
thing called npx we won't really get
into what npx is but for now it's enough
to know that you can just type this top
command npx create react app space and
then the name of whatever you want the
folder that holds your app to be
after typing that first line you can hit
return and you'll see an output in your
terminal that's more or less similar to
this you can see at the very bottom it
says we suggest that you begin by
changing into your directory that you
just created if you didn't choose my
dash app as your folder name then
obviously choose whatever your folder
name is and once you're in that
directory you can run npm start
so you can see on my machine i did that
i went cd into my app and then i ran npm
start sometimes this command can take a
little bit of time to get everything up
and running but once you do you should
see something that looks like this in
your terminal if you remember back when
i showed you how to run react locally
just using those cdns and the vs code
extension called live server well now
we're essentially replacing that you
won't need to click anything in your vs
code using live server but instead
you're running your development
environment through the terminal in fact
after you run this command and it says
compiled successfully it will probably
open a browser window for you and direct
you to localhost colon 3000
automatically and when that opens you'll
probably see the default create react
app screen which looks something like
this
so where exactly does this screen come
from with the react logo well this is a
boilerplate version of the create react
app code that is automatically built in
this new react app that has been spun up
for you if you really just want to start
from scratch what i recommend doing is
just taking all of the files in the
source folder you can see i've
highlighted them all here in my vs code
and just deleting them and then you can
just start from scratch the same way we
have been so far by creating an index.js
file and writing the code that we're
used to writing one thing to note here
is that you don't need to create your
own index.html that is being handled
inside of this public folder and of
course i recommend poking around the
code just to better understand exactly
what's going on but you'll see that
inside that public folder there's an
index.html file that has a div with the
id of root in it so inside the new
index.js file that you create you can
already select that element by the idea
of root when you're using
reactdom.render
and it's a bit small in this screenshot
but you can see that it's rendering an
h1 that just says hello create react app
and in the browser that popped up
automatically on localhost 3000 it
updated automatically for me now usually
any changes that you make to your code
when you hit save it will automatically
refresh your browser every now and then
i found that that becomes a little
disconnected and you just have to go to
your browser and hit refresh but either
way it should update your browser to
reflect what you have written in the
code
and that's it you're all set now as we
continue to go through this course here
on scrimba i still highly recommend that
you do the challenges i give you right
here inside of the scrimba environment
one of the huge benefits of scrimba is
that the environment is already
interactive and it's already set up for
you and so the barrier to getting your
hands on the keyboard typing the code
practicing react is very low so although
you now know how to set up a local
environment please don't feel like you
need to do that every time you're going
to do one of the challenges that i give
you because honestly in this course
we're not practicing how to set up react
apps we're practicing how to write react
and build cool applications with react
but now you have the knowledge you need
if you feel like jumping away from what
we're doing in the course and just
practicing your own thing and being
creative being curious and building
whatever you want to build without
necessarily having to deal with the
scrimba environment and then of course
when the time comes to deploy your
projects to a real website well you're
gonna have to have something local on
your machine that you can push up to
github and to whatever host you're
pushing it to okay sorry that was such a
long aside let's jump right back into
the course and continue to learn
i am coming to you from the future
because you can see in the background we
have our react facts static site almost
completely built out but there's an
issue for anyone who is going to be
using create react app to follow along
with some of the projects that we will
work on and namely those issues are when
we need to load css styles and when we
need to load images in create react app
in scrimba this will just kind of work
out of the box but if you're using
create react app to follow along you
might notice that well your site's going
to look something like this
not only are the styles missing but also
our image link is broken fortunately
these are relatively easy fixes you can
go to the react docs to check out this
adding images fonts and files it also
has a link to dealing with css in there
as well you can actually click on the
screenshot to go straight there but i'm
going to show you what this looks like
in vs code so if you are using create
react app it's generally recommended
that you put your styles inside of your
source folder there's much more in-depth
ways to also organize your styles on a
per component basis but for now we're
just going to assume you have one
globalstyle.css
and that's going to live again inside
the source directory and the webpack
instance that's running create react app
behind the scenes is using something
called style loader that allows you to
just import these styles directly into
your index js this might seem a little
weird to just be importing a string that
represents a css file but webpack is set
up behind the scenes to make this work
fine the main issue is that when you
build your project it's going to build
in a way that doesn't have a ton of
different files and folders inside your
source directory instead webpack is
going to bundle everything up into
essentially into one giant javascript
file and that javascript file is going
to live near index.html
and essentially in the end you'll have
an index.html and index.css and an
index.js files that's nothing that you
have to do manually it's just going to
happen behind the scenes for you i think
that will make more sense when we look
at fixing our image issues but right now
by simply importing our style.css we get
our react fax site back to an almost
perfect condition you can still see that
our logo icon in the upper left is
broken so loading images we do something
relatively similar in the code behind me
here you'll see that we have a navbar
component and in that we are able to set
the source directly equal to a string
that has a path to the image that we
need to exist in the navbar however
because this path is relative to where
the navbar.js file currently lives this
is going to break when things get
bundled up into that one giant index.js
file like i mentioned so anytime you
have an image that you want to include
on your site you will likely want to put
your images inside the source directory
and then instead of hard coding the path
directly into our image source we're
first going to import our image from
that path that's relative to where the
navbar.js file lives and we import it
with some kind of name we can call it
whatever we want i've chosen react logo
in this case and then once we've done
that we simply replace our source with
react logo that way when create react
app is bundling up this project it
essentially has a reference to where
that image file exists relative to the
current file and it can create a better
absolute path when everything gets
bundled up so that there isn't a broken
link between your component and the
image that you're trying to use and once
we do that we have our logo back and
running and everything else about this
page is looking good now there is
another way to solve this problem and
that is to put your styles and your
images inside of the public folder
instead of inside of the source folder
however this is sort of gently advised
against if you go to the documentation
there's a whole page dedicated to using
the public folder but if you read
carefully it says there's a lot of
benefits to not using the public folder
but if you really need to you can and
here's how you can click the screenshot
here to go read more about that if you'd
like okay hopefully that answers some of
your questions if you've been trying to
follow along with create react app on
your local machine if not and you're
just working here in scrumba you
essentially don't need to know any of
this until it comes time to start using
create react app on your own machine but
either way it's good information to know
because eventually you won't be just
working here in the scrimba environment
with that said let's go back in time and
we'll jump right into this project
one thing that i really like to do when
i'm starting a new project especially if
i have the design right in front of me
like we do here is to make a sort of
mental outline of the elements on the
page and how i'm going to lay this
project out all that really helps me do
is to make a sort of mental model of how
i'm going to create everything on the
page this can be especially helpful when
you're thinking about layout and how
you're going to place certain elements
in the right spot on the page especially
when you start thinking in terms of
using flexbox or grid to do that kind of
layout
so as a first sort of mini challenge
what i want you to do is pause the
screencast and look at this page try to
determine what kind of elements you
would use what kinds of css layouts you
might use fortunately this project has a
fairly simple layout but i still think
that it's something that will be helpful
for you to practice so pause the
screencast and try to imagine what
elements you would use and how you would
lay them out for this project
there's certainly more than one way to
lay out any given page but the way that
i see this is having two primary
sections the top section which is sort
of a nav bar and the bottom section
which is sort of the main content inside
that nav bar we have a little react logo
the react facts logo text up here and
then a little blurb about what project
this is in this course
already i can start to see that i'm
probably going to choose to lay this out
with flexbox because that's a really
easy way to make sure everything's in a
nice neat line and with flexbox all i
need to do to push this text all the way
to the right is to give an auto margin
to my react fax text here or rather a
margin right of auto so that it pushes
this react course project 1 text all the
way to the right side of my navigation
bar then down below it looks like i just
have an h1 and an unordered list with
some list items so with this kind of
mental outline i can start putting
together what the actual elements will
look like on the page i usually end up
creating some kind of container div so
we'll call it a div with the class of
container and this will just surround my
whole page and then we have our main two
sections that nav bar which we saw at
the top and the main section inside the
navbar we had a couple elements like the
image and then maybe let's call the
react facts text and h3 and this react
course project one and h4 and then in
the main section there was our h1 and an
unordered list with some list items
inside
now in terms of react this can be a
really helpful exercise because i can
start to see that i will probably have
two main components first a custom nav
component which will house my nav
element with its children elements and
second a main custom component which
will house my h1 and my unordered list
with the list items in terms of those
nested items like the image and h3 those
are going to be simple enough that they
won't need their own custom react
component and then i would take my
custom nav component and my custom main
component and probably collect them
together in one more custom component
which i usually end up calling app and
that will be what renders my div with
the class of container and then that app
component since it contains all the
elements on my project will then be
rendered with reactdom.render
so i hope this has been a helpful
exercise for you at least to see the way
that i usually like to break down my
projects if it's a layout that's fairly
basic like this i usually will just kind
of think about it ahead of time without
actually writing it down or putting a
bunch of dotted squares around the
elements or anything like that but once
you've practiced this enough times a
simple layout like this might take you a
total of maybe 10 seconds to think
through but in the end could end up
saving you a lot of time
so now it's time for us to get your
hands on the keyboard we're going to
have a series of challenges which will
help you be the one that actually builds
out this project
hey there i'm jumping in at this point
to let you know that i've created a very
quick figma tutorial throughout this
course and many others here on scrumba
we're going to be providing you with a
figma design file and i do think you'll
find figma fairly intuitive but i
thought it would be a good idea to just
record a quick tutorial to help you
along the first thing you'll have to do
is go over to figma.com and create a new
account and as i was signing up for a
second account just to kind of test this
process i realized that there's actually
a lot of steps so i figured i would walk
you through it first you're going to
click sign up you'll obviously either
sign up with google or you can provide
an email and password i believe if you
provide an email and password it will
have you go verify your email so it'll
send you an email to verify once you've
done that and you come back it will have
you choose which kind of plan you want
figma has a really generous free tier so
i would just start for free you'll click
that button down there when it asks you
to tell you about your team you can at
this point honestly just say skip this
step and then when it says what would
you like to do first i just think it's
easiest to say i'll explore by myself
and when you do that it's going to drop
you into the figma interface now from
that point on i've actually recorded a
whole tutorial using the figma program
that is now over on the scrimba youtube
channel so at this point you're going to
continue on to youtube by clicking on
the screenshot here which will take you
to the video that i recorded and
hopefully that quick introduction to
figma will really help make things
easier for you as you use figma as a
part of your scrimba coursework so click
on the screenshot you see here head over
to youtube when you've watched that
video and you're done you can close that
window come back here to scrumba and
continue on in this course
let's start by getting some of the
projects set up out of the way i've
written some step-by-step instructions
here in the challenge it is going to be
a little bit more involved because we're
creating everything completely from
scratch or almost completely from
scratch so your challenge is to create a
components folder and this components
folder is going to have two files in it
the navbar.js file and the main.js file
for now they should just render an h1
that says something like navbar goes
here in main section here then i want
you to create an app component which
will be outside of the components folder
and have the app component render the
navbar and main components that you just
created then inside of this file the
index.js you will import the app
component and then use reactdom.render
to render that the last step is to go
and get the enter google font
specifically with the weights of 400 600
and 700. once you've selected those font
weights you should see a series of link
tags that you can use to put inside of
our index.html
make sure to put them above style.css so
that we can reference them in style.css
and if you haven't used google fonts
before this one might take a little bit
of extra research outside of scrimba
here to learn more about but i know that
you can do it fortunately google fonts
makes it relatively easy just know that
you can ignore the at import or any npm
options it talks about for installing
this font remember we're not dealing
with any kind of styling right now so by
the end of this challenge you'll just
have a basic white page that just shows
nav bar here and main section here or
something like that
so pause now and work on this challenge
okay let's just go one step at a time
we'll first create a new folder called
components
and inside components we can create a
new file for main.js
and
navbar.js
as always we will import react from
react
and we will export default our navbar
function our navbar component
and for now this is just going to return
an h1 that let's have it say navbar
component
then our main.js is going to be almost
identical we'll just copy this paste it
in instead of navbar component
we'll say main component and we'll call
this element the main element okay i'll
hit save this is just going to bring up
my preview window but that's still empty
so i need to create a new file called
app.js
and inside of app.js again we'll import
react from react we'll also import our
navbar component from
dot slash components slash navbar
and we'll do the same thing for main so
i'll just duplicate that line and change
navbar to main
then this app component we will export
directly here with export default
function app
and we will just have this return
well we want our nav bar to be in here
so we'll say
navbar and we want our main component to
be in here but i want you to think for a
second what's wrong with the way that
i've done this we can see there's a
syntax error so what's wrong with the
way that i've set this up
inside of components we can only return
a single element that element can have
children elements but right now we're
trying to have two sort of side-by-side
components so what we need to do is wrap
those in some kind of container like a
div
so i'll move this div around and indent
those if you remember from the last
screencast we talked about how this
would probably just be set up as a
container so we'll give it a class name
of container we're not going to deal
with any styling now but i might as well
add that class name since i know i'm
going to need it
okay let's go check out our challenge
and see where we are so far so i created
a components folder i created the navbar
and main components already i created my
app component which is rendering the
navbar and main components
so here we are let's import and render
the app component here i will import app
from dot slash app
oh and i am going to be using some jsx
syntax so i also need to import react
from react
and in our index.js i will also be using
react dom so i need to import react dom
from react dom and then i'll use react
dom dot render to render my app
component which i just imported and
we're going to put it inside of the
element with the id of root so we'll use
document.getelementbyid
root and let's hit save and see if we
get our elements showing up on the page
awesome navbar component main component
just like we expected
okay so that completes this part of the
challenge and then the last thing was to
go to google fonts to get the interfont
hopefully this wasn't too terribly
tricky going to google fonts will give
you a couple link elements so i'm just
going into my index.html
and above my style.css i will just paste
in those link elements you can see that
we have this pre-connect to google fonts
this one to g static but then this one
is for our actual fonts here you can see
the font family is enter and it shows
our weights of 400 600 and 700 there
again i'm putting this above my
style.css so that inside of my style.css
i can reference the font family of enter
and my browser will have already read
these other link tags to know exactly
what the inter font is
okay let's go back here and we have
finished everything from this challenge
i'll just do a little bit of cleanup now
we did just cover a lot of ground
however every step that we did here was
something that you should have already
been able to do maybe with exception to
the google fonts if you've never dealt
with google fonts before so if you did
find yourself struggling to get some of
this basic setup done that might be a
good signal to you that it's time to go
back and restudy and especially
re-practice some of the past challenges
that we've done instead of just kind of
plowing ahead in this course the reason
for that is because i'm essentially
going to assume that you understood how
this works from here on and the last
thing that i would want for you as
you're learning react is to just
continue on without actually having
learned some of these basic setup
principles
okay let's jump into maybe something a
little more fun and that is adding some
actual styling and elements to our
project but before we move on i wanted
to give you one more opportunity to
access the figma design file we talked
about this much earlier in this section
but since it's been a while i figured
this would be a good reminder if you
click on the screenshot here it will
take you to the figma file where you can
get access to the design elements for
this like the colors the spacing the
fonts and everything like that when you
click on this link it will take you to a
shared version of this however if you'd
like you can avoid seeing everyone
else's cursors and selections by
clicking on the little arrow at the top
and choosing to duplicate this to your
drafts that'll make it so that you
aren't seeing everyone else's cursors
and selections but also so that you can
make changes to it if you'd like okay
let's do it let's jump right in and
start working on the navbar portion of
our project
okay this is the fun part we're actually
going to make our navigation bar look
the way that it looks in the design
a couple pieces of advice i highly
recommend you reference the figma file
that contains all of the fonts colors
spacing and everything instead of just
looking at this quick reference that
i've put here but this is meant to be
just a quick reference for you if you
need it another thing is i have added a
couple of base styles to our styles.css
i ran into some problems trying to
record this without putting my box
sizing and just because it helps a lot
i'm going to remove the margin on the
body especially to make our
navigation bar go all the way to the
edges also notice that i have included
the react icon small image
here inside of the images folder you can
see that's part of the design up here in
the upper left
so without further ado pause the
screencast and make the navigation bar
look as close to our design as you can
alright let's do this instead of
rendering an h1 i'm going to open this
up and render a nav element because this
is a navigation bar
and inside of there we know we have an
image
we'll give it its source while we're
here
i have to use dot dot slash images
because i'm inside of the components
folder when i'm here in the nav bar and
it's react icon small
dot png
let's just refresh and see if that's
working okay cool
and let's call this maybe an h3 i guess
and maybe this in h4 it really doesn't
matter because well you could just give
it a class name and call it a paragraph
but i'll just call it an h3
and
h4
this one says react fact
and this one says react course dash
project one
okay refresh that and we've got our
elements on the screen now we
talked about earlier how the navbar will
probably be a flexbox
container so i think because i'm only
going to have one nav element on my
screen i'm just going to style the
element nav
if you want you could always give it a
class name as well i'm going to put
display flex we'll say align items in
the center
from the design we can find that the
background color
is this color here it also looks like it
has about 30 pixels of padding on the
top and bottom and 25 pixels of padding
on the left and right
and we can also see from the design that
it has a height of about 90 pixels
okay so it doesn't look like our top and
bottom margin is applying and i suspect
that's either because our image is a
little bit too large or
i think maybe more likely because our
h3 and h4 here have some top and bottom
margin by default
so i think i might just
select the h3 directly inside of the nav
let's say margin is
zero and then let's see if that also
works for the
h4
okay it might be that the image is just
a little too large let's take a look at
the image and it looks like from the
design it's got a height of about 30
pixels
okay so maybe our padding is doing fine
and it was just that the image was a
little bit large
while we're here dealing with the image
i'm going to give it a margin right
just to bump it away from the text there
a little bit we'll say
i think the design shows it's about 7
pixels
that looks pretty good
and let's go ahead and use the margin
right of auto on our h3
just to bump that
h4 all the way to the right side
cool alright well while we're working on
that we can go ahead and give the color
to our react facts so we'll say the
color is
this color from the design
okay that does it for the color let's
get the fonts right and actually i think
all of the fonts on this page are enter
so i'm just going to change that in the
body we'll say enter and then i think a
backup of
sans serif makes sense
let me just comment this out yeah okay
so that's making a difference so awesome
our google fonts are coming through just
fine
i can also see from the design that the
react facts logo words there have a font
weight of 700 so we'll bold those up a
little bit
or maybe that's the default doesn't look
like it's making much of a difference
and then let's do the same thing for our
h4
it has this color from the design
and it looks like it has a font weight
of 600 okay that's making a slight
difference so that's good
and it kind of looks to me like react
facts maybe needs to be a little bit
bigger and yeah i can see from the
design that it has a font size
of something around 22 pixels okay
that's looking awesome now when i can
avoid it i usually don't love to style
things with their native components if i
don't have to maybe just for practice
sake i'm going to go into my nav bar and
i'll start providing some class names
here so let's give a class name to
everything
on the page let's go
class name equals and then up here maybe
i'll use something kind of like bem
syntax i'll say this is part of the nav
block and the element is the icon and
then we'll say this is the nav block and
the element is the
it's kind of like the logo text
and this one is part of the nav and
let's call it the maybe like the title
of our project here and what's nice
about that is i don't have to do these
kind of nested selectors anymore my h3
was
nav logo text and i can also select my
nav title
and change these other selectors as well
and oh one thing i've learned about
scrimba is i have to make sure i save
this when i change my class names before
i come to the css otherwise the css
updates live but the markup does not so
once i hit refresh there that kind of
put everything back the way it was
awesome this is a really excellent start
frankly most of what we did here was
just css instead of actually doing react
but my goal with this course is not just
to focus entirely on react i want to
synthesize some of the information you
have been learning so far including
revisiting the css and markup and stuff
like that as much as we can frankly in
this first section of the course we
aren't doing much of the detailed side
of react we mostly have just learned
some of the very basic syntax but i
think it's important for us to kind of
remind ourselves of the past information
we've learned by practicing it here
so the next thing we're going to do is
fill out the body section here or the
main section here there's a couple of
gotchas with this that we're going to
actually address later but whenever you
feel good about everything we've done
here in this challenge then let's move
on to the next one
okay let's work on this main section
here i do want you to skip two aspects
of the design right now we're not going
to worry about changing the colors of
these bullets and we're not going to
worry yet about adding this logo over
here to the right
everything else though is fair game for
this exercise so pause the screencast
and work on this task
all right let's go ahead and
make this into a main element this is
another semantic html element
and it represents the main section of
our app here so we will
call it that and it looks like it really
only has two elements in it it's got
this h1 and an unordered list with five
list items
so that should be relatively
straightforward
and it says fun
facts about react
we have our unordered list
and i'm going to hit option shift down
to create copies of those so i don't
have to type them out manually every
time
and then i will actually go ahead and
just copy and paste the text from the
figma file so you don't need to sit and
watch me do that
all right let me move this over just a
tiny bit
and let's hit refresh
okay that's a good start let's get some
of the design aspects going here
i've got my main element and i think i
feel okay styling that as the main
element because i will probably only
have one well i know that i'll only have
one
and we will give it a background color
which we can go ahead and grab from the
figma file
okay and well this highlights some
issues here now i haven't set up my
body or my main element to be a full
height and it looks like maybe the
collapsing margin i'm guessing this h1
has a margin on top which is causing
this whole section to collapse down
below so let's give first of all the
main section a height of let's try a
hundred percent yeah sometimes that
doesn't work maybe if i give my body
a height
of
100 view height
and let me refresh this
well okay you know what i think this is
highlighting another problem that i was
planning on addressing later so for now
what i'm going to do is actually move
this background color to the body so
that it does cover everything okay and
that'll be a good enough start we'll fix
this a little bit later but it did
highlight the fact that what we had here
is our main section is not taking up the
entire body here in a couple of
screencasts from now we'll see why
that's a problem but for now i'm just
going to put my background color on the
body
okay and i probably actually don't need
this height of 100 right now we'll come
back to that later
oh however i do want to give it some
padding and it looks like from the
design i have about
55 pixels it says 57 we'll just go ahead
with 57
on the top and bottom and then about 27
pixels on the left and right and well
you know what i think that margin this
looks a little too much i'm gonna guess
that the margin of my h1 here is a
little bit high let me just check that
if i set this to margin zero yeah that
normalizes it a little bit more
so instead of selecting all h1s let's go
here and give this
a class name
and similar to the last one i'll say
this is the main block and it's the
title
element
and that way i can be a little more
specific about which h1 i want and again
i need to refresh this in order for that
class name to apply and awesome okay the
sizing is looking good let's get our
color correct now our
h1 here also has a font size of about 39
pixels
and everything else needs to be white
maybe i'll just color the entire section
here yeah that'll work okay awesome well
now that i have removed the margin from
my title it looks like my unordered list
is bumping a little bit close to my
title rather than giving my title a
margin bottom to push it down i
personally prefer to have elements push
themselves away from other elements if
that makes any sense and when i see this
i think of the unordered list as being
too close to the h1 as opposed to the
other way around that might not make any
sense that's just how my mind is working
i'm going to give my
unordered list a class name
let's say this is main dash dash we'll
say facts
and we will select our main facts and
i'll give it a margin top of it looks
like the design says 46 pixels
okay now actually i just looked at the
figma file and noticed that our title
actually has
a slight change to the letter spacing
so i'm just going to copy and paste that
here and
yeah that compresses our
h1 a little bit actually quite a bit
so we will go ahead and leave that there
sometimes these rules like this are
really easy to overlook if you aren't
looking closely in the figma design
something that's really nice is i can
actually just copy all of the rules if i
need to
and paste them here and then i can
decide which ones are actually making a
difference or are necessary now i
already have that one i can just comment
these out
this one's technically making a slight
difference i'm not terribly worried
about it
the font size we already specified
font weight of bold is already the
default font style of normal and so
forth i can get rid of some of these as
well
but we can see this one actually did
make quite a bit of a difference so it's
good that we put it in there okay now
these are really close together so i'm
going to select all of the list items
under main facts i'm doing this just so
i don't have to give a class name to
every single li or give the same class
name to every single list item there
and actually let's go ahead and do the
same thing i did before i'm just going
to copy some of these font styles that
we have inside of figma
and see if
any of them made a difference i don't
need that
that's not making a difference
that's already the default
uh that makes a tiny difference maybe
i'll leave it in there it did separate
them a little bit i'm guessing however
i'm going to have to apply some padding
to these so let's give a little bit of
padding there's a relatively new css
property called padding block that
allows me to only specify the padding on
the top and bottom in one go
let's start with 10 pixels and see how
that looks and
yeah that looks fairly accurate
another thing i'm noticing is that the
text is actually wrapping around here
and mine is not it's going all the way
to the right this probably isn't much of
a problem if i did want to fix that i
could probably just apply a max width on
my list items that way it's not taking
up the entire left to right maybe
something like 400 pixels
and yeah that seems to wrap it a little
bit and awesome this is a great start
we're only missing two minor things
we're going to change these colors of
these bullets to be the same color as
our logo up here and we're also going to
add this little react logo over here to
the right however both of these have a
little bit of a gotcha to them so i
thought it would be good to do them each
as a separate assignment and that is
what we're going to cover next
originally my plan was to give you a
challenge to color the bullets and make
them just a little bit larger like we
have in the design however as i was
researching this i came across a
relatively new css property or rather
pseudo selector that makes this
challenge extremely easy so just this
once you can sit back and relax i'm
going to show you just how easy this is
there's a little bit of a gotcha with it
but i included a slide here that shows
you the mdn docs for the marker pseudo
element
and believe it or not this very
specifically selects the bullets on list
items
and even look at this example it's
changing the color and it's making it a
little bit larger with its font size
that's exactly what we want to do you
can click this slide to go check out the
docs poke around these allowable
properties and of course you should
probably play with this a little bit but
fortunately this is a really easy thing
for us to implement i'm just going to
copy this
and add my pseudo element selector for
marker
one thing to keep in mind is that this
is not accepted by all browsers however
safari firefox and newer versions of
chrome have all adopted the marker
pseudo element selector and i'm certain
as time passes this is going to become
even more widely accepted and therefore
i feel pretty confident using this
method for accomplishing this task
so simply enough i can change the font
size to let's say something like 1.4 rem
and sure enough that made our bullets a
little bit larger now as i was playing
with this i noticed that if we get too
large let's say three rem things become
pretty misaligned and at least at this
time when i was researching i could not
find a good way to realign these bullets
with the text so in my playing around i
found that 1.4 made the bullets larger
without getting them misaligned with the
text
so for now we have that limitation i'm
just going to work within that and say
the font size is 1.4 rim it's not quite
as large as what we have here but that's
okay
and then again simply enough i'm just
gonna go take the color of our text here
this is the blue color that we want and
stick it right here as our color and
sure enough we have the blue color on
the bullets easy peasy well i hope you
didn't become too comfortable letting me
do all the work because in the next
screencast we are going to add this logo
and by we i of course mean you in a
challenge so that's what we'll do in the
next screencast
i actually debated a little bit whether
or not i should include this as a real
challenge for this section only because
it touches on some css that you may not
be super familiar with but in the end i
settled on remembering that you guys are
capable and you can use google to your
advantage just like a real developer so
here it is i decided to add it in your
challenge is to place that gray react
logo in the background we have that logo
here under images as react icon
large.png something important to know
about this icon is that it is actually
half of the react logo it looks from the
design like maybe it's a full react logo
that's just bleeding off the page but if
you look closely once you put this react
icon large on your actual page you'll
notice that it's only half of a logo at
first that threw me off that just had to
do with the way that i exported it from
figma honestly i think it makes our job
a lot easier as we're placing it on the
page
so just keep that in mind as you move
forward one last little piece of advice
i'll give you is to add this background
image to the main element it probably
would work just fine to add it to the
entire body element but i'm going to be
doing it to maine so you might as well
do it to the main element as well
again google is a developer's best
friend so don't be afraid to use google
while you're trying to solve this
challenge pause now and work on adding
this background image
okay hopefully you found this wasn't
actually that big of a deal so i'm going
to add
first the background image to my main
element here i'm going to use the url
function so i can specify the location
for these images this is relative to my
style.css file so i'm going to say dot
slash images slash
react icon large.png
okay and we see that it automatically is
repeating around the entire page so
that's where the background
repeat comes in and we want to say no
repeat
of course here by default it puts it in
the upper left of our page or rather the
main element and this is where
background position comes in now
background position is actually a
combination of background position x and
background position y
in fact let's start out there we can say
background position x that's my position
to the left and right i want to push it
all the way to the right this is where
having half of a logo becomes pretty
handy for us because it automatically
looks like it's bleeding off the side of
the page and then with background
position
y
we can specify something like top which
is where it is now or bottom
bottom i think is a touch too low
although center is maybe a touch too
high i can also use percentages so we
can split the difference and say
something like 75
and now that we've seen these as two
separate properties i actually can just
combine these and say background
position which is background position x
and then i'll use a space and then y of
75 percent and that simplifies it a bit
if i really wanted to i could use the
shorthand background property which
would be background and then i would
just copy and paste this one first space
this one space this one honestly i
always forget what the background
property is short for so i'm actually
going to leave these as three separate
properties so that in the future it's
really easy for me to remember what each
of those pieces means
and awesome this represents a
combination of everything that we've
learned so far about react let me go
ahead and clean up this challenge
now of course we've been spending a bit
of time in css land here and as i've
mentioned i still think that's a really
important thing to do even though our
main focus in this course is to learn
react it's really important to
synthesize some of that other
information that you have learned in the
past so that it doesn't become stale to
you and you just forget it that being
said in the next screencast let's spend
some time looking back at everything
that we did learn about react because
that's actually what we're here to learn
and at the same time we'll take that
opportunity to have a quick quiz and to
look at a self-assessment project that
you can do on your own
so that's what we'll be doing next
you've done a great job so far in this
course before you just plow ahead to the
next section it's time for a solo
project this is meant to be a chance for
you to flex your new react skills that
you've been learning about so far in
this section but this time without the
training wheels and there's going to be
a few of these throughout this react
course and these projects serve a really
important purpose they're meant to be a
tool for you to gauge whether you are
actually ready to keep moving forward in
the curriculum or not unlike the
challenges that i usually give you i
won't be walking you through a solution
to this one instead i'm going to be
asking you to sort of go out on your own
to build this project that said you're
not actually completely on your own
we've got a thriving community here on
scrimba that's very willing to give
feedback on your code we'll talk more
about that in just a minute but first i
want you to keep in mind that no one
here is giving you a grade for these
projects like they would if you were in
school one of my personal objectives is
to shift people's understanding of how
learning occurs in school we're trained
to complete the project for the grade
but here you're completing the project
to test yourself and to practice so
skipping one of these solo projects will
really only deprive you of the best
chance you have to test out your skills
and to really help you decide if you
grasp the concepts that we've been
learning so far okay with that guilt
trip behind us let's actually take a
look at what we're building for this
project you're going to be building a
digital business card everything here is
static and you can see there's actually
two different designs that you can
choose from in fact if you click the
screenshot it will send you to the figma
design file you'll see that there's
actually more designs including a light
mode version of these designs and what
you can do is just choose the one you
like the best and build that one when
you get to that design file make sure to
click the little arrow at the top and
choose to duplicate to your drafts and
as far as actually coding the project
goes i recommend that you just build
your project here in scrimba on this
screencast if you look in the very lower
right you'll see a menu with three dots
if you click that there's an option to
fork this screencast to a new scrim
doing that will make a duplicate of this
project that you will have in your own
account so that you don't have to worry
about losing your work
you can see i really didn't give you a
whole lot to work with here we have a
very basic html file that has our div
with the id of root an empty index.js
file some very basic styles and the two
dependencies that you'll need to get
react setup
okay let's come back to the requirements
of this project first of all i want you
to be building this project from scratch
which is why i'm not giving you any
starter code at all next and probably
pretty obvious i want you to fill in
your own information for the digital
business card here and while you're
building it i want you to make separate
components for the info section which is
what i'm calling this whole top half up
here the about section which is really
just this header and a paragraph the
interest section which is another header
and paragraph and a footer section which
has the social icons
while you're working on this solo
project make sure to share your work in
fact you don't even need to wait until
you're completely finished with the
project you can be asking for code
reviews and help all along the way if
you click the discord icon here it will
open the scrimba discord server
specifically to a channel called i built
this but in reality you can share your
project in any of the channels that make
sense to do so in and then for anyone
who is learning in public and likes to
use twitter you can click this twitter
icon which will open twitter and
pre-populate a new tweet where you can
include a link to your project so that
you can share it to the world
okay i wish you the best of luck and i'm
looking forward to seeing everyone's
projects
awesome job building some of your first
react projects i know that these are
just static sites and so far you're
really not seeing the benefits of using
react to build these kinds of projects
but now that we have some of the basic
react syntax under our belts we're ready
to start dipping our toes into a few of
the really neat features that react has
to offer as a framework but first let's
take just a minute to recap what we've
worked on so far in this section
in the beginning it can be really
helpful to know why we even care about
react in the first place we learned
about how it is composable and
declarative what those terms mean and
how that's beneficial to us as web
developers
then we learned about the jsx syntax and
how that allows us to write code that's
much more familiar to us because it
looks like we're writing html code
inside of our javascript then we saw how
we could actually apply the composable
nature of react by creating our own
custom components
for example in our react fax site we
created our own components for the main
content of our page but also for our
navigation bar
obviously in this case our navigation
bar and our main sections are pretty
simple but hopefully you can imagine as
your sites get more and more complex how
the ability to segment each of the
pieces of your page into its own
components can be a really beneficial
thing and soon we'll be really tapping
into the power that comes with that as
we learn more about react
then we started learning about how we
can style our projects because well
obviously adding css is one of the key
things that we need to make it look
polished truthfully there are a ton of
ways to add styling to react for now
we'll just be sticking with css classes
because they're familiar and all of
these things combined have enabled us to
create our own static pages in react
like i mentioned because we've only been
working on static things so far you
might not yet be understanding why we're
using react in the first place but i
promise we're gonna get there and i
promise it will be worth it before just
moving on you should celebrate your wins
over in discord there is a today i did
channel if you click on the screenshot
here it will take you there and you
should let everyone know that you have
just completed the first section of the
introduction to react also this might be
a good time to realize if you've been
sitting down for too long or watching
too much of this in one sitting make
sure you take a break your brain needs
to rejuvenate itself especially with all
the new information you've been learning
so once again congratulations on
completing this section you really
should be proud of yourself when you're
ready to jump deeper into react i will
see you in the next section
now that we've covered the basic syntax
and concepts of building a static page
in react we're now ready to jump into
the next phase which is learning how to
use data to create our web pages
in regular html and in the react code
that we've done so far all of the
content that we're displaying on the
page has been hard coded directly into
the react components and it turns out
this has some major limitations which
we'll be discussing in this section
first let's look at the project that we
just made this little react facts page
all of the data on this page was
actually hard-coded directly into the
components themselves but now let's look
at this section's project which is a
clone of the airbnb experiences page up
near the top we have some elements that
are likely just hard-coded pieces of
data however when you get toward the
bottom and you have a list of different
experiences you can probably imagine
that there isn't a developer sitting
around waiting for a new experience to
become available on the airbnb website
and then immediately going into the code
and updating this list to include that
new experience
instead the data that's living in
airbnb's database is what will be
driving the list that we see here and
once you start thinking in terms of
components on a page that are actually
being driven or displayed based on the
data that underlies the page you'll
start to see the same architecture
existing all over the web
basically any e-commerce site or page
that has any kind of list on it is
probably not using anything hard-coded
into the code of the page but instead is
using the data that lives behind it to
drive the content that exists on the
page
if that's confusing at all don't worry
we're going to dive into the specifics
and see exactly what i'm talking about
just like before you can click on the
screenshot you see here to go to the
figma design file for this sections
project and also just like before when
you get there you'll see a screen that
looks similar to this i'd highly
recommend that you click on the drop
down arrow near the top go down to
duplicate to your drafts and choose this
option to create an editable copy that
will live in your own drafts instead of
trying to use the one that is shared
amongst everyone coming to this page
once you click duplicate to your drafts
you should see a little modal at the
bottom that pops up that says that the
file was duplicated to your drafts which
also includes a quick button that you
can click to go directly there and by
the way you can click any of these
little screenshots to go to this design
file as well
so let's see what we're going to be
learning the first thing that we'll be
diving into is a concept called props in
react props is one of the major topics
in react that will help you create
reusable and composable react components
and so we'll be spending a pretty good
amount of time covering the concept and
the syntax of props
and the other major topic we'll be
covering in this section is how to
create react components from an array of
data
this is what will allow us to create
those designs like in our airbnb design
here where we have a list of items that
we won't need to manually update anytime
the data behind it changes
now before we jump into some of those
more crucial topics in react the first
thing we're going to do is spend a bit
of time creating the top half of our
project here and i'm going to say
something that might shock a few of you
and that is that if you already feel
very confident in doing styling in react
like we did in the last few screencasts
of the last section i'm going to give
you permission to skip the next few
screencasts where we talk about
designing the nav bar at the top and
designing this hero section up here now
this isn't a free pass to just skip
those sections if you feel at all like
you need additional practice using
styling and react i highly recommend you
do not skip those practices however i
did just want to warn you ahead of time
that we will be spending a bit of time
working on some of those design aspects
before we jump into the main topics for
this section so again click on the
screenshot here to open it in figma
create a copy in your own drafts and
then let's jump right in
we're going to start off this section as
mostly a review of what we learned in
the last section which was how to create
our own custom components the way that
we'll be reviewing that is by first
building the top section of this project
which is really just static elements you
can see up at the top we have a little
navigation bar well it's not even a
navigation bar it doesn't lead anywhere
but we'll call it a nav bar and that's
what we'll be working on in this first
challenge after this we'll build this
little photo grid and the text down here
and those will be two separate
components a navbar component and what
we'll call a hero component
you can click on the screenshot you see
here at any time to be sent to the figma
file in order to look for the design
specifics and because we already
hammered it in in the first section i'm
not going to have you build this
completely from scratch so let me walk
you through what we have so far in
index.js we're simply importing app and
rendering app our app component is well
basically as simple of a component as it
could possibly be at this time
and this is also where your challenge is
to build the navbar component
i've also included the airbnb logo image
as well as the photo grid image which
we'll get to in the next challenge but
in this challenge the airbnb logo is
this little airbnb logo in the
navigation bar that you'll be working on
now
the last couple things you'll notice is
that i have the styling about as basic
as it can be at this time and i've also
already imported the poppins google font
that you'll notice is used in the design
file as such when you're setting the
font family you can just say pop-ins but
in this screencast i don't think you
need that yeah this nav bar doesn't have
any text it just has the image
okay let's go pause the screencast and
build out our navbar component
i think what i'll do even though this
isn't going to be a particularly large
application i'm going to add a new
folder called components
and that is where i will put my new
navbar js component
in navbar i'm going to import react from
react
and export default my navbar function
i'm going to use the semantic nav
element
here
and the only thing we really have in
here is an image so i'll use the image
element
and i'll provide the source which will
be dot dot slash images since i'm now
inside of a components folder
slash airbnb dash logo.png
okay we have our component built
obviously this image is not sized
correctly so as soon as we get it
displaying it's going to look a little
bit funny but in our app.js let's go
ahead and import our nav bar
from dot slash nav bar or actually it's
dot slash components slash nav bar
and then for our app component let's
instead of rendering this h1 we'll put a
div as our wrapper for the elements we
put here
and we will render our navbar
okay again i bet our logo is pretty huge
yeah that's much larger than we expect
but that's okay because now we can turn
to the css in order to style this
because this app will be pretty limited
in size and i'm only going to have one
nav element i'm just going to directly
style the nav element i can see from the
design that it has a height of 70 pixels
and of course that's not going to stop
our image necessarily from expanding
beyond the borders of that nav however
in order to center that logo and get it
over there on the left and everything i
think i would like to just make this a
display flex
i think that's also going to
yep our logo will be confined within the
flexbox because now it's a flex item and
it's automatically resized to fit within
its boundaries
if i add a little bit of background
let's just do something temporary we'll
say background color is blue that lets
me see exactly what i'm working within
and i bet if we just add some padding we
will get to resize that airbnb logo a
little bit smaller let's give it about
20 pixels on the top and bottom oh
that's already looking a lot better and
we'll say maybe 36 pixels on the left
and right that'll just bump it a little
further to the right then if we look on
the design we can see that there's
actually a box shadow on the bottom of
this nav bar it kind of helps separate
it from the rest of the body this isn't
always a perfect way to go but you can
actually just copy that css directly
from figma and paste it you can see when
it was designed it might not have been
perfect we have some weird decimal
values here but for now i'm not going to
be too concerned about that
it's a little difficult to see with our
blue background so let's get rid of our
blue background and awesome we can see
that's looking pretty good one kind of
strange bug i noticed when i was
practicing this earlier is that on a
safari browser this airbnb logo will
sometimes stretch the entire width for
some reason of this navbar so before i
move on i'm going to go to my nav bar
and give a class name to my image here
let's call it nav dash dash logo
and i'll hit save so that we can style
that in our css we will select nav dash
dash logo and if i give it something
like a max width of 100 pixels that
fixes the problem in safari
awesome this is a great start to our app
in the next screencast we'll pick up
with another challenge and complete the
hero section which is right below and
that will conclude the review at which
point we can move on to the topics for
this section
the next part of this review is for us
to now build our hero component that
includes the photo grid this h1 and this
paragraph
to make things easy for the photo grid i
exported all of these photos as a single
png so you don't have to worry about
laying out these images in a really cool
way like this
just as before you can click this
screenshot to go to the figma design
file for the specifics the font being
used is that poppins font that we're
pulling in through google fonts so you
can set the font family to poppins from
a design perspective you might also
notice that this image grid is centered
in its container whereas the text is
left aligned although obviously there's
this padding here
so your challenge is to build the hero
component pause the screencast and work
on this challenge
i'll work backwards this time i'm going
to duplicate my navbar line that i'm
importing and change this to hero even
though this component doesn't exist yet
we'll do the same down here and render a
hero
i'm not going to hit save because that's
going to cause this to crash instead
let's go ahead and create our hero js
file
we will import react from react
and export default
a hero component
and first let's get our bear element set
up i'm going to return maybe we'll call
this a section element since it's a
section of our page
and we can see we have an image element
an h1 element and a paragraph element so
i'll include those now
i'll go ahead and just paste in the text
of these from the design file
let's add our image source
and that'll be from dot dot slash images
slash photo dash grid png
and just like our logo this is probably
going to be a little too big for us yep
if i scroll down though i can see some
of this stuff popping up here that's
good it's a good start i'm going to set
us up for some success with the css just
by giving us some class names
let's give the image a class name of
maybe hero
photo
we'll do the h1 is a class name of
let's say hero
dash dash header
and we'll do the same for the paragraph
let's call it hero dash dash text
i'll hit save and then we'll go over to
our styles so we can style some of these
up one thing that i've liked doing in
the past is if i'm going to have a
section that represents an entire
section of my page i just will style the
entire section element or the section
element directly and give it something
like a padding of 20 pixels
that way if in the future i want to use
sections as well sections of my web page
it will automatically have the padding
applied similar to what we did with our
nav bar i think i want to make this
section a display flex but i'll have it
be in a column direction that'll make it
really easy for me to center this photo
grid but keep these left aligned
i don't want to do that on all of my
sections however so i think i'll go back
to my hero and i'll give this section a
class name
of hero
and that way it's acting kind of like
the hero container
and
let's style our hero to be display flex
with a flex direction of column
i have to hit save over here so that
applies okay that's already looking a
lot better
i'm going to make this just a little bit
bigger so we can see how it compares
one thing i noticed when i resize that
is my image is growing probably
infinitely to fit this container because
i'm working in a fairly small space i'm
really only designing for mobile right
now but i think what i want to do is
give my hero photo
something like a max width of it looks
like in the design it's around 400
pixels and we can see doing that is
making it align to the
left side there
so let's give this the flex item
property of align self
to the center
okay well the only other thing i notice
when i'm looking at the design is that
my h1 and my paragraph are spread a
little ways apart oh and they're not the
correct font family quite yet so let's
actually give the entire body
a font family of
poppins
and we'll give it a backup of sans serif
and let's see
oh whoops not popping poppins
okay and yeah that's making a difference
awesome and then i'll come back down and
i'm going to simply style my hero header
and let's specify a bottom margin
so margin bottom of it looks like it's
about 16 pixels in the design and i
think my paragraph might have some
margin that's automatically applied i'm
just going to style my hero text
to have a margin top of zero
okay those are sitting a little closer
together a lot like the design
okay i know that was a little bit
lengthy to work on mostly css here but
like i said i really think it's
important to be synthesizing some of the
past things that you've learned before
they you could say atrophy or get stale
and you just forget them especially as a
friend and developer there's almost no
way to completely escape css if you hate
it and hopefully if you love it then you
really enjoy these reviews so with this
top half out of the way now for the rest
of this section we'll be learning what
we need to know in order to handle the
bottom part of this app so that's what
we'll start doing in the next lesson
let's jump right in and start building
an instance of our card component the
main purpose of this exercise is to
really illustrate how we're not quite
yet prepared to build a series of
components like we have down here so for
now you're just going to build out one
instance of our card there's a few
things that i've done for you i've
created first of all this card component
so you won't have to build this from
scratch and right now we're just
rendering one instance of our card
component you'll notice too that i moved
our hero out and commented it out this
just so we didn't have to keep scrolling
down in our app in order to see the
progress that we're making and let's go
to card.js and look at our challenge
your challenge is to build out the card
component and for now just hard code in
the data for this first one with katie
zafirus
for some of the notes only render one
instance i already did this for you also
the little star icon and the photo of
katie zafirus are here in our images we
have katy zafirus.png and star.png i
just talk here about making sure to
include all of the pieces of data that
we have and again that the main purpose
is to show that we have some limitations
currently in our understanding of react
so don't worry about the fact that
you're just hard coding all of this data
into the card component for now
all right it's time pause the screencast
and work on this challenge
okay so when i look at the card
component that we have in the design i
think what i'll do is make one div that
will surround everything in the card
both the image and all of the data below
i'll probably put all three of these
pieces of data and this little star
image into its own div so that i can use
flexbox to make sure that they're all
center aligned and then i'll probably
just put this life lessons with katie
zafirus in a paragraph and these prices
here in a paragraph i may end up putting
this bolded section in a little span
inside of that paragraph just to make it
bold
if you were feeling adventurous you
might have put this little badge here
i'm going to ignore that badge for now
we're going to cover that a bit later so
let's get some of the elements on the
screen here we're not going to have an
h1 instead we'll surround everything
with the div
i think i'll go ahead and just give this
a class name now of card because i
already know i'm going to be styling
this the very first thing i have is an
image
and we'll hard code in our source that's
going to be in dot dot slash images
slash katy
zafirus.png
i'm sure this is going to be a bit large
as well so i'll go ahead and give this a
class name we'll say car dash dash image
and then like i mentioned i think these
elements here we've got the star the
rating the rating count and the location
all here in a line so let's create a div
maybe we'll call this a class name of
card stats
and we'll put in our image
which will have the
star.png as its source
then i think just to get these other
things in line i'll use an inline
element like span so let's go ahead and
create
i'm going to have three spans here
and remember i'm just hard coding in
some data so we'll put 5.0 we had a
parenthesis with a six
and i might actually just put my little
bullet here as well
and then the location was usa
i guess let's hit refresh and see where
we are okay obviously some styling to
handle but at least things are showing
up
after those stats i think we just had
two more paragraphs so let's go ahead
and create a couple paragraphs we have
life lessons with katie zafirus
and here we had from 100 was it 136 i
guess it doesn't really matter per
person
all right let's see where we are
okay well we have the elements on the
screen let's start doing some styling
here i'll go over to styles
first i'll start off with my card and it
looks like from the design that it has a
width of about
175 pixels and while i'm here i'm
noticing that the text of this card is a
little large i think i'll just style all
of that right here we're going to say
font size of it looks like it's about 12
pixels okay that's starting to look
better
i had my card image which is looking a
little large and in fact the image is
spanning outside of the boundaries of
the card so if i add a width of a
hundred percent yeah that's much better
and from the design it looks like we
also have a bit of a border radius looks
like maybe nine pixels
awesome the image is looking good then
we have this div that contained our
image and our three spans i think we
called that card stats
and like i mentioned we're gonna make
that display flex
and use align items to the center
okay and my star is looking pretty huge
compared to the other things i can't
remember if we added a class name to the
star not yet let's go ahead and add a
class name
and maybe we'll call it card dash dash
star
then
i'll hit
refresh somewhere so we can see those
styles right away
card star
looks like the height is about 14 pixels
okay that's looking a lot more
manageable
in the design the
review count of six here and the
location are both in gray i think what
i'll do is actually just create a bare
gray clasp that isn't specific only to
this card just because it seems like
something i might want to do with a few
other elements so i will give both of
these spans a class name of gray
and then
since that's a little bit more of a
generic style i think i might move it up
maybe just right here below the nav
we'll create a gray class and
we'll just say that the color is the
kind of grayish color from the design
so i just copied and pasted that
straight from figma i need to go and
refresh here okay we have a bit of a
light gray tint there the only other
thing i think i might do is change this
to bold right now that seems like
another thing i might want to do
elsewhere if i just want to bold this
text i suppose i could surround it in a
b tag or a strong tag i think i'm going
to actually surround it with a span
so that i can style that span and just
do that in line we'll surround the from
136 dollars we'll give that a class name
i think again i'll make this generic
we'll just say bold and in my styles.css
we'll add a bold class
that sets the font weight to bold
and let me hit save over here
awesome let's give ourselves a little
more room okay this is certainly looking
good enough for now hopefully as you
were building this you could start to
see some of the limitations that we have
with the way that we built it especially
by hard-coding all of this data directly
into the card component so in the next
screencast let's start talking about
what the problem is with the way we
currently have this and that will set us
up perfectly to learn the solution to
this problem
i assume many of you watching the last
screencast were thinking to yourselves
okay i'm creating this card component
but because i'm hard coding the data in
it's not going to be reusable i've
updated the google slide to show you
maybe a more realistic version of the
design that we're looking for because
we're not just going to have the same
experience with all of the same data
inside
these kinds of repeated components are
found everywhere online and if you just
start looking for them you will see them
everywhere i pulled up screenshots from
some of the first designs i could think
of in amazon every component or every
product is going to have a repeated
element
here's imdb that has something that
looks relatively similar to what we're
doing and here's apple which has
different product components which
really just have an image and a title
image title image title
and you can imagine that when a new
movie comes out to put on imdb there
isn't a developer out there that is
actually typing in new html or copy and
pasting the html that they already
created and then just changing out some
of the data but instead these components
are actually data driven on imdb for
example all they need to do is add a new
movie to their database which includes
things like the cover image the rating
the title and so forth and then the
website will automatically update to
include a new movie in its list here
we're going to cover the data aspect
later but for now the main problem we
have is that our component is so
hard-coded that we can't really reuse it
in any meaningful way and in react this
is where the concept of props comes into
play now in my years of teaching react i
have found that props can be one of the
more difficult subjects for students to
grasp and so what i plan on doing is
taking the topic and just spreading it a
little bit thin over a few different
screencasts and you'll get your hands on
the keyboard and get to really practice
with it so that you can understand the
concept of props
so let's jump right in and get started
let's start by understanding the basic
concept of props and react
what you see here is just a plain
index.html file we haven't introduced
anything dealing with react in this i
want you to take a close look at the
elements that you see here and see if
you can figure out what's wrong with
them
let's start with the anchor tag an a tag
an anchor tag is intended to link you to
another place but currently we don't
have
an attribute like the href specified
without an href this link is essentially
useless we need the href property in
order for us to send someone to another
page maybe like google.com
similarly the image element is basically
useless without any kind of source
property we need to add this source
attribute or property in order to
specify exactly what image will be here
we could put the path to a local file or
we could put the address of a file
that's hosted somewhere on the internet
input is interesting because i think on
its own it actually will
yeah it actually will put an input box
that we could type into if we wanted to
however there are attributes or
properties that we can add to the input
that will make it a lot more
let's say beefed up or capable for
example i can add a placeholder that
says something like first name and that
suddenly makes the first name text
appear inside of my element on the page
or there's ones that have even more
consequence to them like the type
property if i change the type of this
input to something totally different
like submit
now it changes from an input text box to
a button similarly i could change it to
radio and it completely changes the
visual look of this input these are
concepts that i'm sure you're already
very familiar with let's look at a
similar parallel example in javascript
here i've written a function that's
called add two numbers together and it
just hard returns one and two think for
a second what is wrong with this
function it's syntactically correct but
what's wrong with the function like this
well it's very very limited in its
capabilities right now if i call add two
numbers together it will always return
three essentially it's a useless
function now you might already see where
i'm going with this if i add some
parameters like let's say a and b to
this function now i can dynamically add
and return the result or rather the sum
of the two numbers that i pass in
and with the small addition of these two
parameters that i've added i now have
sort of beefed up this function in a way
that it's capable of adding whatever two
numbers i want not just the hard-coded
one and two that used to be there again
these concepts should be familiar to you
by now but this is just a primer for us
to understand the concept of props in
react
in both of these instances in javascript
and html we can see that passing
additional information to our
maybe elements or in this case functions
allows us to reuse these elements or
functions in multiple different ways so
with that primer under our belts let's
look at another conceptual parallel that
is a little more visual
let's try to understand props with a
little bit more of a visual example this
is a screenshot taken from youtube and
as you spend more and more time with a
framework like react you will begin to
see these patterns of elements on the
page that are repeated pretty much
everywhere on the internet for example
if you look here you'll see that there
are multiple components being displayed
here but all of them have essentially
the exact same structure
they each have an image toward the top
that takes up about half of the height
of the component
each of them has bolded text that
represents the title
there's the view count showing the
number of days ago that it was published
there's even little time stamps embedded
inside of the image in the lower right
and as i've mentioned before there
certainly isn't a developer at youtube
that every single time a video is posted
to youtube they go in copy the code from
an old tile and paste it in again so
that it can exist on the site instead a
developer has created a single component
maybe let's call it a video tile
component and has made that component
flexible enough to take in as a property
the image and the title the view count
the number of days ago it was posted who
posted it the time stamp and so forth
and as you become more experienced and
react and you start to see these
patterns for yourself you'll begin to
realize that they can be nested inside
of each other
for example not only do we have repeated
video tile elements here but we have
something that let's suppose is called a
video list each one of these is made up
as a parent-child relationship of video
tiles even small things like on the left
side of the page you can see that these
are probably individual components that
are taking in properties to help them
display something slightly different in
this case it's probably just two
elements there's an image and there's
some text
so that's probably enough of the
conceptual i think you're starting to
understand the concept now let's go back
to react and we'll start looking at how
this is actually applied in code
before we can continue on with props we
need to take a quick aside to talk about
something
we've learned how our components will be
returning jsx which is a special syntax
of javascript or rather it's something
that's created by react and allows us to
write our react code in a very
declarative way however one of the most
common things that you'll find yourself
doing is trying to insert values from
javascript inside of your jsx
right now we just have some text inside
of our h1 but let's assume we had a
value like first name
maybe this is
joe
and a last name
let's say shmo
think for a second how would you change
our h1 to no longer say hello world but
instead to say hello joe shmoe
well we can probably see ahead of time
that just trying to input first name
last name
or maybe even adding a space in there as
if this were regular javascript
isn't really going to work if i do this
i'm going to get the literal text of
first name plus last name
interpreted as the text content of my h1
fortunately react has made it really
simple to interpret something as
javascript instead of text when it's
inside of a jsx element and that is by
simply surrounding it with a single set
of curly braces almost like it were an
object
so at this point before i even hit save
i'm going to give you a quick challenge
simply enough i want you to finish off
the h1 that we have here so that it says
hello joe schmo and actually let's put
an exclamation point in there for a good
measure
pause the screencast and do this
challenge
well if i hit save we'll see that it
interprets the joe correctly instead of
saying first name it's now taking the
value of our first name javascript
variable and inserting it here and then
of course the rest of this text is still
there if i were just to surround last
name then i would get a little bit
closer but i still have my plus and my
quotation marks
so at this point i can just get rid of
those put a space in between my two
values
hit save and there we go hello joe
schmoe the way i like to think of this
is that as soon as i start seeing jsx
the interpreter sort of goes into jsx
mode
anything after this greater than symbol
is going to start being
considered the text content or in the
case of having nested elements other jsx
elements and we're currently in what you
could call jsx land however as soon as
we see this opening curly brace we
switch back into our javascript mode or
javascript land and then anything inside
of my set of curly braces will be
considered javascript once i get to this
closing curly brace i'm now back into
jsx which is why i have an actual space
in the text between my first name and my
last name
then it sees my curly brace again so i'm
back in javascript land the closing
curly brace tells me i'm done with
javascript i get the exclamation point
as part of my actual text
and then i close off my jsx tag
now once i enter javascript land i can
actually do more than just take in
values from my javascript up above in
fact anything that i put inside of my
curly braces can be run as javascript
code let me clean up this challenge
really quick
something that's important to note is
that anything i put inside of my curly
braces will be run as regular javascript
code
so i'm not limited to just pulling in
values like this for example i could do
something like say i have a new date
which is a new date object
and then change this to something like
it is currently about
and then run some javascript code inside
of my curly braces
saying date dot
get hours
and then let's say we want to do a
modulo 12 so that we get the am pm hours
or rather like on a 12 hour clock
i hit save and there we go it's
currently about three maybe i say
o'clock
and that's because for me when i'm
recording this it's currently 3 21 pm
and in fact i wouldn't even necessarily
need to create my date outside of here i
could say new date
dot get hours and i'm going to get the
same result even without doing it out
here because anything that i put inside
these curly braces will be run as
regular javascript now personally i
think it's a lot more readable to do the
actual javascript outside of my
return value in my jsx so if i were
doing this in the real world i'd
probably say something like const hours
equals date dot
get hours modulo 12 and then inside of
my render down here all i'm doing is
putting hours
and of course we get the same result
that way one thing that's nice about
doing it this way is you can sort of
separate the logic that your component
is running with the display that your
component needs to show on the screen so
for example let's say i wanted to say
depending on the time of day good
morning good afternoon or good night
well i could do all of my logic up here
to determine what should display after
the word good for example
i want it to say good afternoon because
for me right now it's afternoon
i could do something like this and i'll
probably speed this up so it doesn't
take up too much time
all i've done really is created a
changeable variable let time of day and
then said if the current hours is less
than 12 it's morning if it's between 12
and 17 then it's afternoon and otherwise
it's considered night i probably should
make something for evening because 5
o'clock p.m seems a little bit early to
say goodnight to someone but whatever so
here's another mini challenge for you
okay your challenge is simply to fix the
h1 below to use the time of day string
that we determined in the code above
pause the screencast and work on this
challenge
simply enough all we really need to do
is remove the hard-coded afternoon put a
set of curly braces and then say time of
day now of course because it is
afternoon for me this will still say
afternoon i suppose i could just trick
this maybe a change just to say if it's
between 12 and 1 then we consider it
afternoon but otherwise it's good night
i should be able to hit refresh and sure
enough it says goodnight i'm going to
change that back so that's not so weird
okay with that concept we are primed to
now jump back into props and to see what
the syntax of props actually looks like
to help guide us through learning the
syntax of using props and react we're
going to look at this little contact
book that i created here as you can see
in our app component everything is hard
coded each one of these divs which i
separated with a little space in between
each one represents one of the contact
cards but of course all of the data is
hard coded inside which means if i ever
needed to make a change especially to
something like the styling i'm going to
have to make that change to every
instance of this contact card that we
see here
before we can really talk about props
though we have a challenge for you and
that challenge is to create a separate
component called contact which as the
challenge shows will be in a different
file and then i just want you to choose
one of the contacts that we have here to
move into that file essentially you can
just copy and paste one of these
contacts over into your contact
component
then once you've moved one of these
contacts over to the contact component i
want you to import the contact component
and render four instances of it here
inside our app component while you're
working on that part of the challenge i
want you to think ahead what's going to
be the problem with doing it this way
okay pause the screencast and work on
this challenge
okay so i'll create a new file called
contact.js
and in contact.js we'll import react
from react
we'll export default
our function contact
and for now we're just going to copy and
paste one of the contacts let's choose
mr wiskerson here
okay that should have been easy enough
inside of app we will then import
contact from our contact file
and then instead of completely deleting
all of these because i think i want
access to this data i'm going to
actually move them
down
outside of my component and then just
comment them out that way i still have
access to them but they're out of the
way
and now i'm going to render four
instances of my contact component if you
didn't make it this far or you didn't
take the chance to think ahead what's
going to be wrong with doing it this way
i want you to think now what's going to
be wrong when i create four instances of
this contact component
well if i hit save we get
for mr whiskerson's
and as much as we left mr whiskerson we
still need the data from our other
contacts here in our contact book why
exactly is this happening well when we
copied one of the contacts and pasted it
over we pasted the data with it just
like a function
let's say add two numbers
that takes no parameters and simply
returns a hard-coded amount in this case
one plus two every time we call this
function it will always give us the same
result in the same way our contact card
has that data embedded inside of it or
hard coded in it and therefore it's
going to show up every time we make an
instance of that component now similar
to how we instead will usually pass some
parameters to a function which make it
more flexible and reusable i can say
return a plus b and now suddenly i have
an infinite number of possibilities with
this function because all i need to do
when i'm calling it is pass in the real
values that i want this function to use
we can do essentially the exact same
thing in react
the remainder of this screencast is
going to be focused on how we pass data
into our contact component and in the
next screencast we're going to look at
how we can consume that data from our
contact component so that we get back to
a working state where we have four
different contacts in our contact book
let me delete this function we'll go
back to app.js and focus here on our
instances of the contact component just
like we talked about how html allows us
to pass attributes which can alter the
behavior of the element react chose to
do things in a very similar way however
in html where we are limited to using
only the attributes that are allowed for
any given element for example i couldn't
pass a whatever i want attribute to a
link tag because that's not defined in
the html spec with react because this is
a custom component i can pass in any
property or attribute that i want we
have four pieces of data in each one of
our contact cards that we need to pass
down to our instances of the contact
component so to do that i can add an
image prop or let's call it img
this image prop can be the value of the
path to the image so i'll go ahead and
copy that from mr wiskerson here again
in the next lesson we'll be learning how
to actually consume these properties
that we're passing in but for now we're
just going to be dedicated to adding
these properties to the context
component on our instances now the
upcoming challenge might be something
that you decide you really hate me for
giving to you i'm going to do one more
of these props and then i will update
our challenge to give you a chance to
practice typing out your own props to
each one of these contact cards i'm
going to put this on its own line
because i already know i'm going to be
adding a bunch of these
the next piece of data that i'll need in
each one of my components is a name so
let's choose to call it name
i'll come down here and just copy mr
whiskerson's name
and pass it in and this is the point at
which i'll update this challenge for you
okay once again i promise i'm not doing
this to be mean but i do want you to do
a little bit of busy work mostly just to
get your hands on the keyboard and start
practicing what it's like to add your
own props to this contact component
remember we get to decide what we call
these props we could call this whatever
we want but of course that's going to be
more confusing so i'll stick with name
the other two pieces of data we still
need to pass down are the phone number
and the email so finish up the first
contact first by adding a phone and
email prop and then i want you to fill
out all the data for the remaining three
contacts with the image name phone and
email props
all of the data of course can still be
found here so you'll have a bit of
copying and pasting to do pause the
screencast and add the rest of our props
to our contacts
okay hopefully that wasn't too painful
for you and hopefully you got a good
sense of what it's like to add props to
react components i'll finish up this
first contact together and then i'll
probably skip over the rest so let's add
a phone prop here
i can just come down and copy mr
wiskerson's phone number
and we'll add an email prop as well
and we'll copy this as well
now i'm going to go ahead and finish up
these contacts but i'll skip over that
so you don't have to watch me
monotonously copying and pasting the
data from below
okay that wasn't so bad was it at this
point i can come down and get rid of
this old version that we have here just
to clean things up a little bit i'll
also clean up our challenge
and at this point you probably can see
that things are a lot more organized
sure we still have a good number of
lines of code here but the data is the
primary focus
we can see exactly what data we're
passing into our contact component and
then our contact component contains the
specific display logic on how the data
should be used
of course at this point we haven't made
any changes to the contact component so
if i hit refresh what do you think will
happen
well hitting refresh won't change
anything we're still going to have four
instances of mr wiskerson because
essentially what we have now is a
function like our add
to numbers that takes parameters a and b
but still is returning hard-coded data
so even if we call add two numbers or
let's say yeah let's call this numbers
and we pass in 5 and 10. it doesn't
really matter at this point that we're
passing in 5 and 10 because the body of
the function is still returning hard
coded numbers
so in the next screencast let's see how
we can make use of the properties that
will be passed into this component so we
can get back to a place where we have
our four different instances of our
contact card
in the last lesson we learned about how
to pass values into our components using
a very similar syntax that we're already
used to with attributes in html
in react we don't call these attributes
we actually call them properties or
usually for short just props
unfortunately it's very easy to get the
data that we're passing into our
components inside of our component
itself
right here just like a function that
takes parameters i'm going to put the
word props
in truth i could call this whatever i
want in fact i'll show you exactly what
happens
i'm going to console.log
what we called whatever
and let me make a little room here open
the console and hit save
now four things got logged to the
console i want you to think for a second
why did it console log four times
a console logged four times because i
have four contact instances
every time react rendered one of my
contacts it ran the console log line
inside of the code of that component and
if you look closely you'll see that we
have four properties in that console let
me copy one of them out here so i can
actually reference it
we got four properties here if i clean
these up each onto their own line
you can see that what we received what
we're calling whatever is an object that
has properties that match exactly with
what we put here as our prop inside of
the component here let's see what
happens if i maybe change img to
something like the whole word of image
again i can change these to whatever i
want them to be
so now when i hit save if you look down
below
the first item is receiving an object
that now has an image property all
spelled out whereas all the other ones
are still receiving an img property
anyway i don't want to go down that
rabbit hole too much so let's come up
here and change whatever to props
because props is what you'll usually be
calling this and at this point i want
you to pause the screencast and see if
you can figure out how to use this
object that has all of the properties we
want
to update our component this one's going
to take some critical thinking but i
want you to really think through it see
if you can figure out how to essentially
make it so that our components are not
for instances of mr wiskerson but rather
have the correct data and images
displaying here let me type that out as
a real challenge
okay there's your challenge pause the
screencast and see if you can make it so
that essentially we finish this little
contact book where each one is its own
separate contact
pause now and work on this challenge
well if props is an object and i can
access the values of that object by
using props dot for example name
props dot image then all i really should
have to do is update this hard coded
data for example the name here
to curly braces props dot name
of course if i didn't put the curly
braces in there it would literally
interpret the text props.name and then
all of the names would say props.name
when i surround it with curly braces
awesome my names are changing obviously
nothing else has changed so let's go
ahead and do the rest i'll start with
these easy ones we'll get
props dot phone
and
props dot email
okay the phone and email are coming
through correctly now the image
this one may have been a little bit
trickier for you but simply all i'd have
to do is erase the entire source
including the quotation marks and put my
javascript here
because the value that's coming in
through props.image or img
is already a string
it's going to fill in the string value
for my source i hit save and there's all
of my values
ah but here's a bug i introduced this
when i was teaching the concept
hopefully this is a good chance for you
to do some debugging
if you didn't i want you to see if you
can figure out why the picture for mr
wiskerson is not coming in pause the
screencast and try to fix this bug
well right here for our image source
we're assuming that we're receiving a
prop called img
back in app.js however i did change this
to image so i'll change this back to img
hit save and now the photo for mr
wiskerson is coming in just fine now i
hope i'm not belaboring the point
understanding props is one of the most
crucial things that you can do in react
when you're learning so yes we've spent
a lot of time covering props however you
will use props every single day of your
rehacked life so this is a really big
milestone if you feel like you've
understood everything in react that
we've talked about so far you should
really congratulate yourself pat
yourself on the back and probably at
this point take a little break don't try
to bite off too much more than you can
chew and i do want to show you a little
cool trick that we can do with our props
here in the next screencast
okay it's time to give you a prop quiz
sorry i couldn't help myself
like before your task is to read through
each of these questions to actually
click into the editor and type down your
answers don't forget in scrimba if you
have any changes that you make to the
code you can always save it as a note so
that you have access to it later you can
even record your own voice talking over
the top of the note if you wanted to
keep an audio note and all of those are
saved here in your account on scrimba so
pause now answer the questions through
this quiz and then you can hit play and
we'll go through the quiz together
number one what do props help us
accomplish
well just like parameters being passed
into a function props being passed into
a component help us make that component
more reusable
as you become more and more experienced
in react you'll realize that there are
times when it makes a lot of sense to
pass props into a component so that it's
reusable and other times when it might
be possible to pass props into a
component but it's just not always
necessary i can't tell you how much time
i have spent trying to create a
component that's very reusable and then
ended up only using it one maybe two
times that's just one of those things
that will come with experience as you
write more and more react code
remember when we pass props into a
component it could be data that actually
gets displayed as a part of that
component or it could sort of be like
metadata that you're passing into the
component that in a way configures it to
act a certain way
either way it helps us make any
component that we create more reusable
so that we can keep our code as dry as
possible
okay so number two how do you pass a
prop into a component in the same way
that you pass attributes to html
elements like a source attribute for an
image you essentially do the same thing
when you're passing props to a component
so if i have my own component like let's
say my awesome header i'm using a
strange name just to make it very clear
that this is a custom one you can pass a
prop of your own choosing like maybe
title
into that component
that brings us to number three can i
pass a custom prop like for example blah
blah blah to a native dom element so for
example a div with the lowercase d
well the answer is no so we come to the
next part why not
and that's because under the hood when
react sees a regular html element that
we're trying to render we express that
element through the jsx syntax and that
jsx syntax actually returns an object
and the object describes the actual dom
node that should be created when we add
an attribute to a regular dom element
like a lowercase d div the object that
this jsx creates is expecting to be able
to add this property to the dom element
and since dom elements don't have an
attribute called blah blah blah i can't
just choose the props that i want to add
to native dom elements like this div
so let me try typing out a summary of
that
so the answer is no because the jsx that
we use to describe those native dom
elements we want react to create will
eventually be turned into real dom
elements and real dom elements don't
have whatever properties let's say
properties or attributes specified in
the html specification which as we all
know doesn't include properties like
blah blah blah
okay i think we understand that concept
how do i receive props in a component
simply enough
the parameters to that component
function will receive a value called
props which of course we could name
whatever we want but by very strong
convention will be props
and that leads us to the last question
which is what data type is props in the
component when i receive it this
parameter which we're calling props is
an object which means if i want to
access the properties of that object i
use dot syntax so
props dot
whatever the prop was that i passed in
let's use blah blah blah because that's
what we said before okay awesome job on
that quiz if you struggled with any of
these questions of course don't hesitate
to go back and review the things that
we've recently learned and when you're
ready let's move on
at this point in the course you should
be somewhat familiar with the concept of
object destructuring however just in
case we'll do a quick recap
say i have an object called person
in es6 and later i can destructure the
properties of that object in order to
get simpler to use variable names for
example if i wanted to log person.phone
i obviously could just use console.log
person.phone and everything would work
just fine however in certain
circumstances it can be nice to
destructure this object and pull out the
property names for your own use that
looks kind of like this i might say
const and then i'll use an object syntax
say image comma name and then set that
equal to person my object
what that does is it declares two new
variables img and name which i can then
use in order to
say console.log the name
if i open the console you can see i'm
getting mr wiskerson here
so that's the concept of object
destructuring the reason i bring that up
is that it's a fairly common thing to do
this in react with the incoming props
that you receive the parameter that you
put inside of your component will be an
object that represents all of the props
that your component received so what i
could decide to do is just destructure
that object immediately as i receive it
inside of my function here which means
that i could say curly braces image
name
phone and email it's important to note
that i can't rename this to something
else like image unless i do a little bit
of trickery using colons like image
colon image but we're not going to be
too concerned about that for now
the point being i don't get to change
the name of the prop while i'm bringing
it in i need to make sure that it's
exactly as the prop was being passed in
at the time that the component was being
rendered
if i decide to destructure my object
like this then i will need to change
some of my code here you can see if i
refresh suddenly i get an error that
says props is not defined so let me give
you a challenge to fix it
okay your challenge is to fix our bug
now that we've destructured the props
object
pause the screencast and work on this
challenge
well by destructuring our props we're
essentially declaring four new variables
up here image name phone and email so
instead of props dot image i can just
reference image and name
and
phone and email i hit save and
everything should be back to normal yep
there we go the main reason i wanted to
show this is just because you will
certainly run into react code that
either has the full object of props
written here or very commonly the
destructured object which pulls out each
of the individual components or rather
properties of the props object frankly
you can write it either way in my own
personal experience i've experimented
with both ways and in the end i found it
a little bit easier in my opinion to put
the props object here and then reference
props dot image and name and so forth
the only reason being if i decide to
declare other variables inside of my
component let's say right here it
becomes less apparent which variables
came in as props and which ones were
declared inside of my component
so that's my reasoning for usually
sticking to putting the whole props
object it does cause a little bit more
of the clutter here by having props dot
everywhere but honestly that's okay with
me
whichever way you choose just try to be
consistent with it there certainly are
other things that we will learn about
props as we go forward but now it's time
for you to get your hands on the
keyboard and start practicing the things
that we've learned about props
well it's been a minute since we've
started a new react app totally from
scratch so one last time i promise the
last time i'm gonna make you do this i
want you to set up a react app
completely from scratch i guess as a
reminder scrimba is doing a little bit
of magic for us when we pull in these
dependencies it's setting up our react
app basically for us but i just mean in
the coding part
i want you to get a little more practice
on doing that from scratch you can read
through the challenge for the specifics
on what you're supposed to do there's
also some extra credit down here that
would be worth looking into if you're
interested and if you were able to do
this top part all by yourself and
although i would like you to include
your own favorite jokes and maybe share
it on twitter or in discord i did
include some jokes for you to use just
in case you didn't have any jokes on
hand that you knew of so pause the
screencast and work on this challenge
since we've done this a number of times
i am going to move through this fairly
quickly so i'm going to import react
from react
and import react dom from react dom
we're going to use react dom to render
an app component which i haven't yet
created but will in just a second
and we'll render it to that div with the
id of root
i'll also import an app component which
isn't yet created so i will create a new
file called app.js
inside of app.js again i'll import react
from react anytime we need jsx in our
code then i'm going to import react
and i will export my component
for now i'll just do a quick sanity
check we'll do an h1
that says hi
okay good we're showing up on the screen
you might notice too i included some
basic styling i changed the font just to
switch things up a little bit
okay and then it says to have the app
component render four or five joke
components
so i will kind of work backwards we'll
have this return a div
that surrounds our five
joke components
and those don't exist so first i need to
import them from a file called joke
and then i need to actually create that
file
so in joke js
again import react from
react
export default
our joke component
okay we'll have this return a little
sanity check h1 for us
joke here
hit save okay our five joke components
are being rendered correctly and showing
up on the screen now if you did struggle
at any point in just this part of the
setup i really recommend that you just
go back spend the additional time you
need to revisit what we've talked about
so far everything here should not be
confusing at this point in the course
and if it is it's okay you just probably
should go back and revisit some of the
stuff that we've learned already
okay now comes the practice for actually
using our props
we know that we need
a setup prop
and i actually copied these already so
i'm just going to paste in the setups
for these jokes
and then we have a punch line now i can
tell that my punch line is going to make
each of these a little bit too long so
while i'm here i'm going to put these on
their own lines
okay and then i have all the punch lines
copied as well
now think for a second i haven't hit
save yet think for a second what is
going to change if anything on my screen
here
you said nothing's going to change then
you're right and that's because i am
passing props in but my component is not
making use of them at all so let's do
that i'm going to receive the props
just for giggles let's take a look at
what console logs when i console log
these props
we see we get five instances of the
props object
so really quick question if i typed
console.log one time how come i'm
getting five console logs
well just like any function whenever i
run it it will run this console log and
in our case because we have five
instances of a joke component it's
running this joke function five times
now because props is an object i can
access the setup and the punch line
through dot syntax i can say props dot
setup and prop stop punch line let's
make this not an h1 but a div
and i don't know let's make these h3s
maybe
and i'll separate each one with a little
horizontal rule
now here's another check for you if you
weren't able to get to this point i want
you to think now how am i going to
actually make my setup and my punch line
display on the screen in fact you can
pause here and actually make that happen
well i can't just say props dot setup
because of course that will make it
literally put the text props dot set up
on the screen to insert our javascript
value inside of my jsx i just need to
wrap it in curly braces i'll do the same
thing here we'll say props dot punch
line
and i need to make sure i spell that
right
and let's hit save and awesome we get
everything showing up now one thing i
just thought of i might want to change
this to something
like a paragraph just to change the
boldness between these two or give it a
little bit of contrast between the setup
and the punch line and i think that that
hits all of the points from our original
challenge here
go ahead and delete this
now we come to the extra credit and if
you were able to complete this extra
credit then you're pretty far ahead
because we haven't yet taught things
like conditional rendering but i did
think that i would just give you a
little sneak peek on it so here's an
example of one of my favorite jokes
that's just a one-liner here over in
app.js i'm going to create another
instance of a joke
and i'll put it at the top so we can see
it more readily now in this case there
really isn't a setup for this one it's
just a punch line so what's going to
happen if i just include a punch line
well we can see that i really don't have
anything being rendered up above here
however if we did go into the dev tools
we would see that up above this
paragraph there's actually an empty h3
sitting up here honestly it's not that
big of a deal the way we currently have
things set up but what if i went to my
joke and instead of just putting the
setup and the punch line i said
something like setup colon and
punchline colon now when i hit refresh
we can see that well it's a little bit
broken here
again this isn't something that we've
taught so i didn't necessarily expect
you to fully grasp this concept quite
yet but as an advanced sneak peek into
conditional rendering something that i
can do is actually only render this h3
if props dot setup exists
one really concise way that we're going
to learn about is to surround my jsx in
curly braces which means that i'm
putting it inside of a javascript
interpretation and then i can say props
dot setup and this h3 we're going to
learn about how a lot of the
neat little tricks that we can do with
react are just using vanilla javascript
principles and this is a good example of
that this is saying that if props dot
setup is a truthy value then render the
thing on the right side of my and
operator here if it's a falsie value
however it won't render anything at all
so i can hit save and it will look very
similar to the way that it looked before
again we're going to talk more in depth
about that it doesn't need to make
perfect sense quite yet and one of the
cool things about this is we could
decide to do it in another way for
example what if instead of conditionally
rendering it this way i decided to say
well the style of this h3 is that it has
a display of
none
when props dot setup does not exist well
i could do that with something like a
ternary i could say the display if props
dot setup does exist then i want it to
be block
but otherwise i want it to be none
obviously this is a much more convoluted
way than what we just saw but it
essentially accomplishes the same thing
the point is we can use those props and
vanilla javascript principles like a
ternary operator or this more concise
and operator to accomplish our goals
i'm hoping this was a helpful practice
i'm really looking forward to seeing
people's best jokes and when you're
ready there's still one more little
thing we're gonna learn about props
before we can finally take all of this
and apply it to our section project
okay i'm sorry that we're still here on
the jokes but i realize there's one more
thing we need to cover before we jump
back into our section project and that
is how can we pass a prop that is not
just a string the concept of props like
we talked about is very similar to the
concept of attributes in html and with
html we always pass in a string as our
data type here however we are not
limited by that in react so far we've
only done strings however because this
is javascript it's react which is
javascript we can pass in any javascript
data type to our components as props so
i want you to think critically here how
might you pass in a prop that wasn't a
string data type let's say for example
you want a number passed to each one of
these jokes that eventually will
represent the number of upvotes and down
votes for this joke or maybe you want to
pass in an array of comment objects
and then you might say i want to allow
people to filter out the puns or only
show the puns in my jokes in which case
i might pass a prop called is pun which
is the value true or false not the
string true or false but the actual
boolean value true or false
accomplishing this uses something that
you've already learned at this point and
so i want you to try and think
critically see if you can figure out how
you would pass in a non-string value as
the prop to your component and be
curious with it play with it actually
give it a try don't just think about it
pause here and see if you can figure
that out
we learned previously that we can jump
back and forth between javascript and
jsx by using curly braces and the same
thing works with our props for example
these three jokes here are all puns so
if i wanted to indicate that i could say
is pun equals and then jump into
javascript and send in a boolean value
like true and then i can do the same
thing for these others and then of
course for the ones that are not puns i
can change this to the javascript value
boolean value of false
and then do the same thing for my jokes
up here up top
actually i'm struggling now to think if
this joke is a pun or not this might be
a pun because it's talking about puns
anyway you get the point by introducing
these curly brackets i can put any
javascript value in here so again if i
wanted to pass in a number i could say
upvotes
is
10
down votes
is two
and if i had an array of comments i
could say comments equals and then this
can get as complicated as i want i can
say an array of objects and maybe those
objects have an author property and it's
got some author id and then the body of
the comment itself and then maybe
there's even a title to the comment and
whatnot of course it's an array so it
could be multiples of those and so forth
i can even put javascript expressions in
here to determine what the value being
passed into the props should be that's
getting a little bit more advanced than
i want to jump into now but the point is
these curly braces essentially give us
free reign to throw any javascript we
want inside of the curly braces and
whatever that javascript expression
resolves to is the value that the prop
will pass down to our component
so let me fix my syntax error here and
go over to my joke component and let's
just console.log
props dot is pun
and you'll see we get a bunch of boolean
values i could even do props
props.comments.title
and actually that's going to cause an
error because i didn't pass a comments
prop to all of them but let's do
props.comments
and we'll see we get a bunch of
undefineds but one of them has an array
of objects
so i think you get the point that's
going to help us as we go back to our
airbnb experiences clone so that's what
we're finally going to jump back into
now
okay we're finally back to our airbnb
experiences clone your challenge is to
pass these props that i've outlined here
into our card component and then inside
of our card component receive those
props and make use of them
as a little bit of a hint and a heads up
there's a couple instances that we're
not passing in strings or strings that
we are passing in that we need to
slightly modify in order for them to
work i guess so that's not too cryptic
the image that we're passing in here
you'll notice is only the title of the
image file it doesn't include any path
to the image itself the astute of you
might know that what we're doing here
still is requiring us to hard code data
into our component and in the real world
that's not what we're going to do
however we haven't quite gotten there
yet in an upcoming lesson very soon
we're going to see a way that this would
actually be structured a little more
realistically
but i want to get your hands on the
keyboard practicing like i always say so
work on this challenge until you can
show our card component looking
essentially exactly the way it is now
but without the hard-coded data inside
of the card itself pause here and start
on that
okay i already know that i'm going to
have too many props to put on one line
so i'm just going to start them on the
next line
and we'll set the image equal to
this string i'm going to copy and paste
these just so i don't make a fool of
myself making a typing error
the rating is going to be 5.0
now this is a string right now i suppose
if we were ever planning on doing math
on this rating then it might be
sensible to change it into a floating
point number here by surrounding it with
curly braces like that i'm not going to
be too concerned about it at this point
the review count
maybe just for good measure and because
i didn't put quotes around the six up
here i'll send in a number
the country will say
usa mostly because katie zafirus is from
the usa
for the title
we'll once again copy this
and the price i'm going to send in as a
number we'll say 136.
in this case i don't think it makes a
huge difference because i'm not going to
be doing any math on this number
probably but what the heck just for good
practice
okay i can clean up this challenge but i
do need to now go to my card component
and the very first thing i should do is
actually receive props here and maybe
just so i'm not flipping back and forth
between the files to see which props i
sent in i'm going to console log the
props
so that i can see them down in my
console
and that will give me a chance to
actually look at the properties that i
sent in
now right away we run into a little bit
of a challenge like i mentioned we're
only passing in the file name and
extension we're not passing in the whole
path but i can't just do string
concatenation like saying dot dot slash
images slash and then plus my props dot
image because this plus is not going to
make sense
now i could do that by surrounding this
entire thing here
in curly braces but i'm going to make
use of the es6 templating string syntax
with these back ticks
and that way i can put
my
dollar sign curly braces now this is
probably starting to get confusing
inside of a template string i can insert
values by using dollar sign curly braces
and that's where my props dot
image will go
however i can't just put back ticks
surrounding everything here because that
doesn't make sense in jsx now this is
the tricky part if i surround the
backticks because they are a javascript
expression
in curly braces then suddenly this
expression makes sense i think this is
probably the trickiest part of this
challenge i'm hoping it didn't frustrate
anyone too much but i totally understand
if it did because it's a confusing back
and forth
remember up here we're in javascript
then we jump into jsx
then with the curly braces we jump back
into javascript and that's why i can use
my backticks
inside of javascript and inside template
strings i can use the dollar sign curly
braces to insert javascript values into
this string i think it's called
interpolation i end my backtick and then
i get out of javascript and i jump back
into jsx
hopefully you could follow all that i
understand if that's confusing
the rest of this should be really pretty
straightforward my rating is right here
instead of putting a hard-coded 5.0 i
can put my curly braces props.rating
instead of my six and i'm actually going
to just put in my curly braces inside of
my parentheses here i'm going to put
props dot review count
again the parentheses is still part of
jsx and therefore will be interpreted as
text the curly brace gets me into
javascript which is why i can then put
my javascript value
and then i get out of javascript and i
have my second parentheses to surround
it
my country i can put props.country
in this paragraph we'll put
props dot title
and
right here for the number i'm going to
leave the dollar sign because i still
want that to exist however the price
that i'm passing in is just the number
136 so i will put props dot price
okay moment of truth let me get us a
little extra working room here i'll hit
refresh and awesome everything looks
like it is still working the same now it
does kind of look like we don't have
this space showing up after our dot but
we won't be too concerned about that
right now okay last thing i'm going to
clean up my console log up here
and excellent we now have a reusable
component as long as every time i create
an instance of my card i pass in these
props i should be able to get different
cards showing up in my list
really great work if you were able to
follow along with this entire lesson i
really hope that this has been helpful
and hopefully you are just as excited as
i am to learn this because this is
giving us more tools in our tool belt
more power for us to create really
awesome web applications in react we
obviously have a lot more to learn but
really at this point you should be
really excited for everything that
you've learned especially if you're
understanding it if you are feeling lost
of course as always go back revisit
these and ask lots of questions in
discord coming up we're going to be
addressing that issue where currently we
are still hard coding this data into our
code here and so that's the next topic
we're going to tackle
this is a total spoiler alert into what
we're about to learn with react and that
is how to use the dot map method to take
regular javascript data and turn it into
jsx elements that react can render so i
figured at this point it would be a
great opportunity to revisit the map
method just in case it's been a while
since you've used it or especially if
you've never really understood it in the
first place
if you fall into that ladder group then
i highly recommend you go check out the
mdn docs on map
look through the examples play with the
code and work with it until you at least
grasp a basic understanding of the
syntax for it because you should already
know map by now i'm going to assume that
that's the case and we're going to work
through these challenges
instead of having you do all of the
challenges right away at once i'm going
to let you do challenge number one and
then we'll go over it together and then
i'll have you do challenge two we'll go
over it together and then challenge
three we'll go over it together so of
course we'll start at the beginning with
challenge one pause the screencast and
work on this challenge
so as a refresher map is a method on
every array because i've declared nums
to be an array nums has a method called
dot map dot map is a higher order method
which means that it takes a function as
its main parameter this is a great
example of a method that is declarative
because under the hood dot map is going
to handle the regular for loop for us
and all we need to do is provide a
function that the map method can use to
run on every single item inside of the
array whatever we return from this
function as part of our return here is
what will get placed in the same index
in a brand new array
and in the end nums.map is going to
return a new array so i need to save
that array in a variable we'll say const
squared
equals the array that gets returned from
numstopmap an important part of this is
that the function i provide to dot map
is going to receive
each of the items in the array one at a
time as dot map loops over the array for
us and runs this function
so if i were to for example console.log
item
i would see
that i get each of the original items in
the array and they each show up on their
own line because this console log is
running five separate times
so all we have to do is simply return
item
squared i could use the math library or
i could just say item times item
and now if i console log squared
i should get this array which was my
original goal
and sure enough there it is okay that
was just to get our feet wet this next
one has a little bit extra challenge
includes potentially some string methods
but again it's just a regular javascript
challenge pause the screencast and work
on challenge number two
okay just like before we'll create a
variable to hold our
destination array or our returned array
let's call it uppercase and we'll get
that by using names.map now above i used
a function declaration like this but
this time i'm going to use an arrow
function just to simplify my code a
little bit it's essentially the same
i can open it up and use return i'll fix
this later for anybody that's yelling at
me that i can simplify this even more
and inside my function i'm going to be
receiving an item now i could call it
item or i think a little more
intuitively i'll call it a name in fact
usually i would call this item
probably num or number let's call it num
just to kind of clean that up make it
obvious what we're working with now with
the name what i want to return is the
first letter capitalized in that string
now i'll be totally honest string
methods are not something i usually just
have memorized i usually end up looking
them up i'm going to wing this and see
how it works essentially what i'm trying
to return is the first index so i'll say
name at the index of zero dot to
uppercase that should be a string of the
first letter that's now capitalized and
then i'm going to add
name dot i think slice will do it and
i'll start at the index of one which i
think will give me the rest of the name
starting at index one inclusive again
this is kind of a shot in the dark so
we'll see how this goes console log
uppercase
and oh i was so close i think i just
need to add my parentheses here
awesome i probably could have done
something like name.slice 0 comma 1
maybe and then change that to uppercase
i also could have done something a
little more complex like surrounding
these in template strings and then using
interpolation to figure that out
and that might help me get rid of my
plus
now i'm just kind of playing around
nope there's my space i don't need a
space
okay that to me is a lot less readable
than what i had before so i'm gonna keep
it this way
i guess that's one of the fun things
about these challenges you can try to
solve it in multiple different ways okay
let's clean this up i'm going to comment
this out and i'll send you now to
challenge number three just to clarify
because we're just working in regular
javascript here i'm not expecting this
to work in react or jsx or anything
essentially all we're doing is taking
this string and then adding what looks
like paragraph tags the opening and
closing tags
on the beginning and the end of that
string of course this is leading to a
point that will then take us to react
pause the lesson here and start working
on challenge number three
okay let's say maybe const elements even
though these aren't real elements and
that's going to be pokemon.map i'll use
my arrow function again and this time
because i'm only going to be using a
single parameter let's see i think
pokemon is both singular and plural
right maybe i'll say mon for monster
because i only have a single parameter i
can get rid of those parentheses and
just put my arrow here and well before i
simplify the rest let me actually open
this up and we'll do it the way we did
it before and then we'll clean it up now
this time around i think it probably
will be easier to use a template string
so i'm going to
put my
paragraph text here and then inside of
my paragraph text i will put my
monster's name let's console.log
elements
make sure that this is going to look the
way we expect and awesome that looks
great now regarding cleaning things up
because an arrow function has the
ability to have an implicit return if i
start that return on the same line as
the arrow
i can clean this up that way i can also
do the same up here get rid of my
explicit return
make it implicit and because i only have
one parameter i can get rid of those
parentheses if you're still feeling hazy
with arrow functions don't worry i'm
kind of with you there but once you do
get used to them they can really provide
a nice simple syntax for you to perform
operations that otherwise might take a
number of lines of code that's another
one of the benefits like i mentioned of
having declarative methods like dot map
it's handling the for loop for us we
simply have to follow the rules and we
get back exactly what we expect now
again what we're ending with here looks
like an array of html elements in fact
if we were to be doing regular dom
manipulation we probably could use these
using the inner html method to have the
browser actually turn these element
strings or dom strings into real html
elements on the screen but since we're
not doing that and we're doing react
we're going to see how we can basically
use this exact same principle to take
data from an array and turn it into jsx
elements that get displayed on our
screen there's one more really small
step that i want to cover before we get
there so let's cover that next
i think now is probably a good time to
remember that jsx just returns a regular
javascript object we can see that if i
were to set let's say a new variable
called element equal to some jsx and
we'll say
just an h1
and then if i console.log element what
we actually get back is just a plain old
javascript object
the properties and the shape of this
object get determined by react in order
to describe the element that react
eventually will be turning into a real
dom node that shows up on our screen
but the reason that i mention this is
because when you get deeper and deeper
into web development and actually
programming in general you'll discover
that most arrays don't end up being an
array of simple strings like we
sometimes use for examples like this
instead it's probably most common to
find arrays end up being an array of
objects
let's keep this example simple we'll say
it's a first name
and a last name in this object
that's because data is usually a lot
more complicated than just what can be
represented by a simple string and so we
use objects to represent pieces of data
in a lot more detail well there's a
little special feature of react and that
is that if we provide an array into what
we're rendering from our component
react will know how to essentially map
over that array and turn it into
elements let me clean some of this up
and show you a little bit more what i
mean let's say we create this array of
colors and i'm just going to put in the
colors of the rainbow
of course i just got done mentioning
that usually we don't have an array of
strings but this is just to illustrate a
point inside of my return when i'm
returning the elements that i actually
want to put on the page i can give react
this array and let it render it to the
page now i can't just say colors because
then it's going to put the actual word
colors on there so i'll surround it in
curly braces and now essentially what
it's going to do is
copy this
basically i could have just done this in
its place
so we'll take this one step at a time
let's look at it this way now obviously
this is not beautiful and we can tell
already that it's essentially just
putting these together as blank text i
haven't taught react that i want these
to be paragraphs or headers or ordered
lists or anything like that now of
course if i do want to use my variable
colors up here i can essentially just
put colors here and i still of course
need my curly braces here when i hit
save i get the same result but now i
want you to do a little challenge to
experiment with what will happen if you
change these from strings into jsx
elements
okay simple enough i just want you to
essentially change these strings into
jsx elements and i said h3 you can do
whatever element you want then i want to
make sure that you hit save or refresh
and see exactly how what we have
currently changes when you do that pause
the screencast and work on this
challenge
okay maybe this is getting into the
realm of busy work but let me do this
really quick
okay let's see what happens when i hit
save
awesome now i actually got a list of jsx
elements that are being displayed as h3s
in some ways it's kind of like react
took the elements here
and just copied and pasted them onto the
screen of course i would need to get rid
of all these commas for that to work
correctly but i get the same result this
way but let's put it back to colors so
that it works the way it's supposed to
work okay now we are poised to take what
we just talked about and reviewed with
dot map and what we just learned about
where react can render an array of jsx
elements and put those concepts together
which will allow us to instead of hard
coding our data directly into our
components like we're doing here instead
we can get data from outside of our
little system map over it and render a
new component for every piece of data
in other words in the next screencast
we're going to see a jokes.js file which
has essentially the same thing but in a
javascript array of objects then we'll
get to pull those in and map over them
create an array of jsx elements and then
render those to the screen so when
you're feeling ready let's go forward
let me walk you through a couple of
changes i've made to the code that we
were just looking at of course you
probably noticed i moved all of our
hard-coded joke components outside of
our component here
and just commented them out so we can
still reference them i've also changed
our jokes.markdown file into a
jokesdata.javascript file now we're not
quite ready to make api calls and then
make use of the data that comes back so
i'm going to be kind of mimicking that
with this jokes.js file that's exporting
an array of these joke objects over in
our app.js i'm going to import the jokes
i'll say jokes data
from that file dot slash
jokes data
and we can see that if i console.log
joke's data i should get the array of
jokes okay great
now combining what we just learned with
dot map and with creating an array of
jsx elements i can put those two
concepts together what i'm going to do
is create a variable let's call it joke
elements and this is going to be not an
array that i'm defining right now but
instead the array that gets returned
when i call jokesdata.map
inside of my.map i'm going to take a
look at each one of my joke objects
and what i can return i'll do this on
its own line just so we can see a little
more clearly what's happening i'm going
to return a joke
component
however i can pass the data from this
individual joke object to my joke
component
so maybe this is a good opportunity for
you to put on your thinking cap and do a
quick little challenge
your challenge is to see if you can pass
the props to our joke component in the
correct way and then of course render
our joke elements array so that when
you're all done all of our jokes show up
on the page again pause the screencast
and see if you can complete this
challenge
each of the joke objects that i am
looking at inside of my dot map
is each of these objects that we see
here so they have a setup property and a
punchline property
which means over here i can say my joke
has a setup prop and this has to be
spelled exactly this way because our
joke component is expecting props.setup
this setup prop will be equal to and
then i need to use my curly braces
because i'm leaving jsx and going into
javascript we'll say joke dot setup now
it just so happens that i'm using the
same name for the prop that i'm passing
to my joke component props dot setup
and the object property that i chose in
my actual data set up here however it's
not always going to be the case that
these are the same if for example these
were question instead then over in
app.js i would still say setup because
i'm the one that gets to choose what the
prop name for my component is but then
my actual data would need to change to
joke dot question now a question doesn't
always make sense in this case because
they're not all questions but hopefully
that illustrated a point
and next i will need my punch line and
this is going to be joke dot
punch line again because the actual data
has a punch line property in each of
these stroke objects
now i'm not quite done i can hit save
nothing's going to show up on the screen
and that's because i'm still returning
an empty div in my app component the
last thing i need is just to render my
joke elements
hit save and there we go we've got all
of our jokes back on the page
now if i clean some of this up you can
see just how much simpler this makes our
lives as react developers and then if i
were being really stingy i could use the
implicit return to just return my joke
element i'm not going to worry too much
about that especially because it makes
it a little too wide horizontally there
awesome okay we have taken a number of
asides once again i'm going to bring us
back to our airbnb experiences clone and
we're going to take this concept and
actually build these separate
experiences in their own cards this time
using data that we get from a file
instead of hard coding things into our
code
make sure you have studied this and
understand it before you move on and
when you're ready let's jump back into
our section project
all right it's time for another quiz
we're going to look at the dot map array
method read through these questions
click into the editor type down your
answers and when you're ready click play
and we'll go through the quiz together
number one what does the map array
method do and i'm referring here to
javascript in general not specifically
react well the arraymap method takes a
function as its parameter and whatever
gets returned from that function will be
placed in the same index of a brand new
array so maybe let's say it
returns a new array
and whatever gets returned from the
callback function
provided
is placed at the same index in the new
array and well yeah that's good enough
theoretically speaking our callback
function we could just hard code
something like return the string hello
and then we would have an array filled
with hellos but usually what we're
trying to do is take items from the
original array and modify them in some
way in fact maybe i'll type that down
with that in mind number two asks what
do we usually use dot map for in react
well in web applications it's really
common for us to have an array of raw
data usually an array of objects and to
want to turn that array of data into
something that's visible on the screen
so in react we'll take an array of data
we'll map over it and turn each of those
items into
some kind of jsx element that gets put
on the page
so more concisely it allows us to
convert an array of raw data into an
array of jsx elements that can be
displayed on the page
and number three why is using dot map
better than just creating the components
manually by typing them out and putting
the props in that we want
using dot map in this way is a lot more
dry
obviously if you think in terms of
something like amazon every time a new
product is uploaded to amazon and amazon
sells that product there isn't a
developer out there who's going to go
copy and paste the elements from a
product and then put in different props
let's say
no instead the data will change and
using something like dot map will
automatically convert that raw data into
something that gets displayed on the
page
one way you could put it like i wrote
here is that it makes our code more
self-sustaining in a way meaning that it
doesn't require additional changes
whenever the data also changes it makes
me think of when we're typing out a c
style for loop and we say something like
4
let i equal 0 and then we use i is less
than some array dot length
this makes it so that if the length of
the array ever were to change our for
loop would not require intervention
instead it would automatically check the
length of the array and that's what it
uses in this parameter in the for loop
alternatively if i just said something
like i is less than 5 but i'm looking
through the elements of an array that
maybe now has let's say 10 elements in
it my for loop is broken and it requires
intervention from a programmer i think
you probably understand so i'm just
going to erase this for loop and leave
it where it is awesome work on this quiz
hopefully you were able to answer all of
these questions when you're ready let's
move on and start applying what we just
learned to our section project
i am coming to you from the future again
because in the next challenge for
anybody who is following along using
create react app on their local machine
instead of following along here in
scrimba the upcoming challenge might
throw you for a bit of a loop
technically speaking what we're about to
do is go back to the airbnb project and
use a data file that includes links to
the local images so that you can map
over it and display those images as well
as the other pieces of data and you'll
see that just kind of works out of the
box here in scrimba but if you're
following along with create react app
you'll get something that looks more or
less like this obviously this is not
ideal the last time that i spoke to
using create react app i mentioned how
it's gently advised against putting any
assets inside of the public directory
however this is an instance where i'm
just gonna recommend that you put your
images inside of your public directory
i'm gonna go to the next slide this has
an animated gif that might take a minute
for some people to load
but you can see that what it's doing is
it's taking the images directory from
the source folder and moving it up into
the public folder the reason i'm
recommending doing this is well first of
all normally you're not going to have a
data file that includes all of the data
you need instead you would actually be
getting that data from some online
resource and second of all because it
just magically works when you move the
images to the public folder things just
kind of start working again so that was
just a quick heads up for anybody using
create react app if you're following
along here in scrimba you really don't
have to worry about any of that for now
okay with that said let's jump in
okay it all comes down to this we are
going to put all the things that we just
learned together to progress our section
project here with the airbnb experiences
clone i've written out your task here
and let me walk you through just a
couple things first of all there's now a
data.js file and this contains an array
of the objects that represent the data
that we're going to be displaying on the
screen part of your task is to import
that data as it mentions map over it to
create our card components kind of like
we have hard-coded here and then render
that array in place of this card
component one little change that i did
make is i changed the country prop to
location and i also made that change in
the data here so in case you were
curious about why that's changed i just
decided it made more sense since we
might have some online experiences
and another thing is you'll notice there
are some properties here that we won't
yet be using like open spots or
description that's okay for now just
ignore those we'll decide later if we
want to make use of them also as i
mentioned in the note here because we
haven't done styling to our group of
components or anything like that yet
they're going to stack on top of each
other because they're block element dibs
for now that's okay don't worry about
them being stacked vertically we'll fix
that later
okay now is the time i know that you can
do it you've worked hard up until this
point hopefully you have studied and
re-watched everything you needed to in
order to understand what we're doing so
let's jump right in pause the screencast
and work on the challenge
all right let's do this first i need to
import my data
and i probably will just stick with the
word data as my variable name here so
we'll say import data from
dot slash data
and maybe just before i get too far down
the road i'll console log this just to
make sure that
i'm getting the data i think i'm getting
okay yeah that looks right
again as a quick reminder usually you
won't be importing a hard-coded data
file we'll be covering api calls and how
to get data from an online source later
but until we learn a couple more things
we're not going to be able to do
anything really except for importing our
data
then down in our component i don't want
to erase this comment because that's my
whole hero section that we commented out
for space sake before
let's take our data and
i don't know maybe call them cards we'll
say cards is equal to data.map
and we'll let map look over each of
those experiences maybe i'll just call
it item for now and then for each item
in that array i want to return
well let me just copy this here because
it's got all the properties that i want
and then instead of having these
hard-coded values i will just replace
them
with the values from our object so let
me just make sure that i get all these
properties right we have
this is called cover image not image so
i guess some of these might change
so that's cover image again this is
another instance where the data had a
different property than what we chose to
call our prop that we're passing into
our component that's entirely okay and
actually ends up being pretty common
especially if you're not thrilled with
the way that the data was designed
oftentimes you're consuming data that
someone else has put in their database
and you don't get to choose these
property names okay our rating let's
look at our data now we have this stats
property and that's where our rating is
so we're going to have item dot stats
dot rating
and similarly with review count
item.stats.reviewcount
so
here
item.stats.rating
and
item.stats.reviewcount
[Music]
okay in the data we have location that's
going to stay the same so location will
just be location item dot location
title i believe was
item dot title and this i believe was
item.price let's just double check those
i like to double check them because
otherwise i might see missing data and
then get really confused about why it's
not working
title price
title and price okay now that we have
created our array of card components we
need to render it
so let's get rid of our hard-coded card
i'll put curly braces because i need to
enter into javascript here my array of
jsx elements is still considered
javascript so i'm going to put that in
curly brackets say cards hit save
and look at that we're getting all of
our experiences showing up of course
again they're vertically stacked each
one has its own unique data being
displayed and awesome at this point we
have covered a bulk of the material from
this section that i wanted to cover and
don't get me wrong we've covered a lot
of things so far there's a lot here to
practice with and as always if you're
not feeling comfortable yet with some of
this material it's important to stick
with it practice it over and over until
you understand it that being said we do
have a couple more things that i want to
cover before we finish off this section
first of all we need to style this so
we'll do that in the next screencast and
then i want to give you a sneak peek
into some of the topics we'll be talking
about in the next section so when you're
ready let's polish off our project here
with some css
okay i've got to be honest with you i
was going to have you style the list of
cards here so that they would horizontal
scroll inside of a container but we've
already spent a pretty fair amount of
time doing css inside of react and so
for all the hard work and effort that
you have put in so far i've got a little
present for you bam we've got the
styling done of course if you're
interested to see how i did this
basically i made a flex container made
it so that none of the items would grow
or shrink as the container got bigger or
smaller and then just set the overflow
to scroll essentially you can check the
css for the details on it i've also
included little tags that will tell you
exactly what i added so that you could
easily see what actually changed
also notice that i used a section
element here to surround our cards that
allowed me both to give this a class
name and give it specific styling but it
also allowed me to make use of our
styles that we put way back in the
beginning on sections so that it had
some padding on the left and right now
there are two things that i want to talk
about here
one is how awesome it is that we are now
mapping over our data because it means
that if the data ever changes our page
will automatically update so if i were
to for example paste in three more items
here i just copied the one and pasted it
again
and then updated our page is going to
automatically update with all of the new
activities that are included in our data
clearly this is a much better way to
work as a developer where the data will
change and your page doesn't need to
your code actually stays exactly the
same and all that really updates is how
that data is being used to display your
elements on the screen the second thing
that i want to cover is this error that
we have been seeing or rather a warning
that we've been seeing that says each
child in a list should have a unique key
prop it's a little bit beyond the scope
of this course to dive deep into why
this key prop is necessary but you will
see this warning anytime you are using
map on data to create jsx elements or
rather an array of jsx elements
first let me go to data js and get rid
of those three extra items we had
now over on our card the way we can get
rid of this warning is by simply adding
a prop called key and it very
specifically needs to be key k ey and i
need to set key equal to something
unique about this individual item in
this case pretty much everything about
these different experiences is unique
the image is different the title the
price however for example the rating is
not different between this first one and
the second one so that's not something i
could use as my key because it's not
unique fortunately when we're pulling
data from a database almost always will
receive some kind of id property that we
can guarantee will be unique because the
database is creating that as a unique
property in the database now obviously i
typed all of this in manually but i gave
it an id so that we could mimic this
concept over in app.js i'm going to
assign the key to be item.id
again i probably could have used the
title or the price for this warning to
go away but when i hit save we'll see
that warning disappears so those were
just a couple of miscellaneous items
that i wanted to cover i'm not going to
put our hero back in quite yet because
there is one more thing that i want us
to talk about and that touches again on
a sneak peek of conditional rendering
and we'll talk about that in the next
cast
a phrase you might hear from the react
community is that people love react
because it's just javascript now of
course under the hood there's things
like jsx which is a little bit of magic
being performed by react but i wanted to
show you what that means by giving you
another sneak peek at conditional
rendering now i've updated the little
screenshot that i have here to show you
this little badge down here that says
sold out and you might have noticed that
in the data we actually have a property
called open spots now i intentionally
set this first one to open spots of zero
so that we could conditionally render
this little badge if the open spots is
ever zero you might remember from the
first time i did a little sneak peek on
conditional rendering the term is
referring to when we only will sometimes
render a part of our page
right now everything on here will render
every time this component gets called
however what we can do is take a look at
props and if props dot open spots let's
say is equal to zero then we can display
the little sold out badge otherwise we
just won't display it at all
now there's two parts that we need to
make this work first of all over in
app.js we aren't currently passing in
the data from open spots into our card
component so the first thing we need to
do is create a new prop called open
spots
set that equal to item dot open spots
another thing you may have noticed is
that we sure are passing a lot of props
into this component we're going to cover
a truncated way to essentially do this
same thing without having to add a new
prop to our card component every time we
want some data from our item but for now
we'll stick with what we know so we now
have a prop called open spots we're
passing in that number value from our
data
right here
now in our card js let's just make sure
that this is working i'll go ahead and
console log props dot open spots
and check our console and sure enough we
get 0 27 and 3 because that's how many
open spots there are for each of our
experiences
so let me get back to what i meant by
it's just javascript first let's go
ahead and actually create a little badge
that will float in the upper left of
this image the way i'm going to do that
is by setting my card to be position
relative and have a div here that's
position absolute of course for now this
div will always show up we'll fix it so
that it conditionally renders as soon as
we have something that looks good let's
go ahead and just hard code in sold out
and i will give it a class name
let's call it card
probably badge
and honestly just to save time i'm going
to paste some styles in here
so that you don't get too bored then on
my card i need to make it position
relative and i need to refresh this
okay now obviously it's hard coded so
every one of these has a sold out badge
and you might remember that the way we
handled conditional rendering before was
we surrounded our div that we only
sometimes want to display in curly
braces and then essentially included a
condition beforehand
now we used a very short version of that
condition which we'll use again i can
say props dot open spots
equals zero
and
the div that i want to render
this is kind of a clever example of how
in react we typically use just plain
javascript to handle things like the
display logic that our component needs
to know about
if this first statement is truthy then
this second statement or this jsx
element will run and therefore get
displayed however if this first
statement is falsy then the second one
will actually never even get called or
run and therefore this div will never
display on the screen so if i hit save
we'll see that now i only have a sold
out badge on the element that had
exactly zero spots in it
technically because zero is a falsie
value i could say that if not
props dot open spots
but that's a little less easy for me to
read and if another developer were to
come see this they might expect open
spots to be a boolean
and so i'm going to keep it as triple
equals zero to be very explicit
now if you actually go look at the
airbnb experiences website you'll notice
that even in our design here we talk
about online experiences
and some of our locations are online the
actual website itself has a little badge
that says online in order to help people
understand that it's going to be well
probably through a zoom meeting instead
of in person live meeting so i thought
i'd show you yet another example of how
we can use just plain javascript to help
determine the display logic of our
components here right now i have this
badge that says sold out now i could
come up with something kind of
complicated by putting my display logic
in here that says if open spots is zero
then display this div otherwise if the
location is online then display another
div otherwise display nothing but as i
was preparing this i came up with
another way that i figured was a little
more concise and so i thought i'd show
that here if you've ever done a code
challenge on well any number of the
websites that exist out there that allow
you to practice code challenges this
might feel kind of familiar
my goal is to dynamically render not
just this entire div but also the text
inside of it so i'm going to set a
variable using let and i'll say this is
badge text then i can just use regular
javascript and say if props.open spots
is equal to zero then i want badge text
to read
sold out or let's put it all in caps to
stay consistent
however if it's not sold out i also want
it to check if props dot location
is equal to online
and if it is then we'll have badge text
say
online
now there's two things that i need to
change with this line of code in order
to make it so that primarily if it's
sold out it has a badge that says sold
out secondarily if the location is
online it displays a badge that says
online but otherwise it displays no
badge at all
in fact let's make this a challenge for
you
okay your challenge is to display the
correct badge text instead of this hard
code sold out
and secondly to only display the badge
when it's either sold out or an online
experience i've given you some hints
basically in the language that i used
for this challenge number two pause the
screencast and work on these challenges
okay for the first challenge to display
the correct text
all we have to do is erase sold out and
instead render whatever the value of
badge text is now of course currently
this will only get rendered if open
spots is exactly equal to zero so we
also need to change our condition upon
which this gets rendered kind of a
clever way that i thought of was well
when we initiate badge text up here its
value is going to be undefined and then
if props dot open spots is zero or props
that location is online then badge text
will have a real value i can use the
truthiness of a real value or the
falsiness of undefined to just say
if badge text exists or rather if badge
text has a real value then i want you to
display the badge
now maybe this is contrary to what i
said before about assuming truthy and
falsey values this one seems a little
more logical to me however so if i hit
save
awesome now we have sold out on anything
that's sold out notice even if it's an
online experience it will prefer sold
out first because that's our first
condition up here
and then if it does have open spots but
it's online it has an online badge
and if it's neither then there's just no
badge at all
now we will be covering conditional
rendering in more detail later however
the point that i'm trying to get across
is that in react we very often use plain
javascript like this kind of regular
algorithmic javascript to determine how
things will get displayed on the page
that might not seem unique or strange to
you until you've worked in another
framework like angular or i think view
as well where there are actually
properties built into the markup that
you see that provide logic for using for
loops or conditional statements and so
forth i'm not necessarily vying for one
over the other but hopefully this sheds
some light into why a lot of proponents
of react will say they like it because
it's just javascript
and along those lines the next thing
we're going to do is go clean up this
card component that is getting pretty
lengthy we'll do that in the next lesson
when we have a component that's in
charge of maybe displaying one or two
pieces of data it's not that big of a
deal to pass each of those pieces of
data down individually as separate props
however we can see our card component is
starting to get a bit lengthy and
honestly we haven't even included things
like maybe there's a description or a
set of tags that can categorize these
experiences
whatever the case might be along the
theme of react being just javascript
what we can opt to do instead of passing
each of these properties of our data
down individually is we can just say i'm
just going to give this component the
entire item object notice i kept key
here that's because it's something
unique that we need to include anytime
we're using map but for all the other
properties of data that i need my card
to know about i'm just going to pass the
entire item object down
of course because i'm changing the
structure of my card over here when i
hit save well everything is broken now
but if at this point you truly have an
understanding of how props works and how
the things that we passed down to our
components can get received by the
component you should be able to complete
the following challenge
fix our component
i'm intentionally being a bit vague here
because i want you to challenge yourself
if you have felt a little bit confused
about props and what exactly this object
is that we're receiving and so forth
this might be a good indicator that it's
time to go back and just review the
stuff practice the stuff that we've
already learned
but if you have felt pretty confident
here then i want you to pause the
screencast and work on this challenge
well one major hint that we can get is
if we console log our props
and it might be a little bit confusing
to read through here but you'll notice
in the console below that there is an
item property in our prop so props dot
item
and that item is the object with all of
the properties from my data it might
clean it up a little bit if i just log
props.item
so with that it means that all i really
need to do is change anywhere i was
referring to individual props as a part
of the props object like props.image i
just need to change it to
dot props.item.image however we are
going to run into one little problem and
what i'll do first is just change
everywhere i see props dot to say props
dot item dot and then the property there
let me hit save we'll see where we run
into a problem so it looks like some of
it is coming through we have our title
our price and our location but it looks
like our review count
our rating and our image are not working
so if you haven't already figured out
why this is broken i want you to pause
the screencast poke around the code see
if you can figure out how to fix the
rest of this component
because we are passing in the entire
item we now are beholden to exactly the
structure and the property names of our
data itself so for example in our
component we were saying props.img
but in the data it's the object dot
cover img so if i replace in my card
component img with cover img
now my images should come back similarly
with review count and rating these were
both part of a sub object called stats
so if i add stats as a part of my card
now props dot item
dot stats dot rating and
review count the rest of that should
come back the way we wanted it now we
can see that our badges are still
missing and that's because way up here
when we're doing this logic we also need
to add props dot item so that we're
correctly looking at item.location and
item.openspots
let's see if that fixes it awesome we're
back to the way we were but now our
component as we use it is a lot simpler
awesome work we are so close to done
there is one more little tweak to
exactly what we've done here that you
might see pretty commonly in react and
so i wanted to make sure that i covered
that before it became really confusing
when you saw it in the wild so that's
what we will cover next
there is one more little trick to
passing properties into a component that
i wanted to teach you about so that when
you see it in the wild it's not terribly
confusing because if you don't know
about it it looks rather confusing this
trick has to do with the object spread
syntax and if you are either not
familiar with it or it's been a minute
since you've done it it's an es6 feature
and i've linked here the mdn docs on
using the spread syntax with object
literals but the idea is that instead of
creating my own prop called item that i
pass the entire object down through what
i can actually do is just
put a set of curly braces and spread the
item into my components props
essentially what this does is it takes
the properties of the data like id title
description price cover image stats
location and open spots and creates a
separate prop for each one of them kind
of like we had before we were passing in
the item individually so it would look
like id equals item.id
title equals item.title
description equals
item
dot description
and so forth and so on until it has
covered every property in our data here
or rather every property in the item
that we are passing into our component
now doing this does fundamentally change
exactly what props the card is getting
because well we just changed props so
that it said props.item because it was
receiving an item object prop doing it
this way means we would basically go
back to the way that we had it before so
if i were to go back to that i do curly
braces dot dot dot item which spreads
all of the properties of this item as
separate props into my card component
back in my card component i need to go
back and get rid of all of my dot items
here okay just like that oh i missed a
couple here
and actually you know what let me leave
those in and we'll see that this is
breaking
and well it looks like it's breaking a
little deeper than it was before so then
when i make those changes in the correct
way hit refresh everything's back to the
way that it should be working
on a personal note i do tend to struggle
with this method of passing data down to
a component only because it obscures
exactly what we're passing to our
component i personally would rather pass
the item down as a very explicit
specific prop that says item is item and
although it does clutter my component a
little bit where i have
props.item.stats.reviewcount and whatnot
i tend to find that at least for myself
when i go back i don't need to first go
to the data understand what properties
are there then go to app and see that
i'm spreading that in then go to the
card and look at what those properties
are i don't know maybe it's just a
personal preference i have tended toward
passing objects down like the way that
i've shown you here for your own sake of
review i'm going to put this back to the
spread syntax just so you can see what
it looks like as the spread syntax hit
save so we see that it's still working
i'm sure as you write more and more
react you'll settle on which one you
like the most or maybe just stick to a
standard in whatever code base you're
working in i'm going to take a second to
clean some of this up so that we buy
some more horizontal space
and last but not least let's go back to
our app.js component let's bring our
hero back in
and let's see how things are looking
awesome
and that folks marks everything that we
had planned to learn in this section so
before we keep pushing forward in react
let's take just a minute in the next
screencast to look back on everything
that we've learned in this section and
give you a chance to complete another
self-assessment project
before moving on to the next section we
have another solo project for you to
work on like we talked about before it's
a great opportunity for you to flex
these new skills that you've been
working on so far in this section but
this time without the security blanket
of me being there to help you
now the next section we're about to jump
into is the heaviest section of this
whole course so it's especially
important at this time that you work on
this solo project to help gauge your own
skills and then decide if you understand
these topics well enough to move on
again it's projects like these where the
real internalization of everything
you've been learning actually happens
so what's the project this time around
you're going to be building a personal
travel journal it's a page where you can
list all the fun places that you've
traveled along with some of the details
and a photo from your trip clicking on
the image of this design will take you
to the figma design file once you're
there make sure to click on the arrow at
the top choose duplicate to your drafts
so that your view of the design file
won't be cluttered by anybody else's
cursors or selections and also so you
can make any edits to this that you want
to make
the quickest way to get started will be
to code your project here in scrimba if
you click away from the google slides
you'll see a little menu with three dots
when you click that there will be an
option to fork this screencast to a new
scrim which will start you off with the
starter code that we have here once
again i haven't given you a whole lot i
did put this boilerplate code in here
for you but that's about all that i've
done for you
so let's take a look at the project
requirements we haven't yet learned how
to pull data from an api but i do want
this page to be data driven so you'll be
creating an array of this data in a
separate javascript file and that array
should contain objects which have
properties for the title location the
link for google maps a start date to
your trip and date to your trip the
description and an image url
if you're using your own photos you can
actually just drag and drop them into
the explorer in the upper left of this
scrimba environment and then you can
just reference the file name of the
image instead of an image url or if you
want you could just use an image url of
an image out there on the internet just
so this was perfectly clear i gave you a
little start here i just took the data
from the design file here on mount fuji
and created an array with a single
object in it this way you at least know
the shape of this object so you can make
a copy of it and put in your own data
once you've pulled in that array i want
you to use the map method and props on
some custom components to pass that data
down to the custom components and have
react display the array that has been
mapped and as is always true in these
solo projects you should make sure that
it's styled and really polished you want
this to be something that you would be
proud to show to someone else
and of course speaking of which make
sure that you share your work again you
don't have to wait until you're
completely done with the project you can
always share your current progress in
discord and ask for some code feedback
you can click the discord icon here that
will take you to the i built this
channel where you can share your work or
if you're doing something like learning
in public on twitter you can click this
twitter icon which will open a
pre-populated tweet where you can share
a link to your project good luck
building your travel journal and i
really look forward to seeing
everybody's finished projects
we find ourselves here at the end of
another section and all i can think to
say is nice work
in this section you have taken a big
stride forward in your understanding of
react let's look at a quick recap of
what we've learned first and probably
most importantly we have talked about
props in react props are one of the most
fundamental topics in react and they
really make it so you can write more
composable code you can see in both of
our projects we have elements on our
page that are essentially reused both in
the airbnb experiences cards here and
the travel journal cards here now that
you know the concept of props and
reusing components with different data i
guarantee as you start paying attention
to the websites and web apps that you
use online you're going to see this
concept everywhere then what props
really enables us to do is use data to
drive the code and map over it in order
to create the website that we're trying
to create
now although there's only two topics
here in this recap those topics are
extraordinarily important as we move
forward as always you should be
extremely proud of what you have worked
on so far so i highly recommend that you
go over to the discord server if you
click on the screenshot it will take you
to the today i did channel and even if
you don't feel like sharing your code or
a screenshot at least post a message in
there that tells people that you have
now completed section two of the
introduction to react course also this
is a very natural time to take a break
from your computer if you've been
working on this for quite a while make
sure that you stand up and move around a
bit get something to eat or drink your
brain does need some time to digest all
of this new information that you've been
learning so even if you need to come
back tomorrow that's completely okay and
then whenever you're ready i will see
you in the next section
you have done an amazing job so far and
now we have arrived at probably the most
exciting section in this whole course
and that is how we can create
interactive web apps in react until now
we have basically just been recreating
static websites in react and of course
along the way we've also learned how we
can use props to create reusable
components in react but really so far
that's only allowed us to create
reusable parts of what is still
considered a static website
if you think of the airbnb experiences
clone that we just finished building we
left it off in a state that really still
didn't allow for any kind of
interactivity with the user on the real
airbnb website a user can click into
those experiences they can save them to
their favorites and then of course they
can actually book that experience and
pay for it so that lets us know that
there is so much more that we get to do
with react and that's where you've
arrived in this section to help us
better understand what i'm talking about
let's take a look at the difference
between static websites and dynamic web
apps
the static web pages that we've been
doing so far they're really read only
they don't allow for any kind of changes
to the data and that's probably the
defining attribute of a static web page
especially in the early days of the web
but still pretty common today you'll
find static web pages like a blog a new
site recipe sites and a bunch of others
that really don't allow you to change
any data but rather just to read or
consume the content that exists on the
page
in this section we are going to be
learning how we can use react to also
create dynamic web applications and the
defining attributes of these web
applications is that they are both read
and write in other words the user has
the ability to change the data that
drives the app
as such they tend to be highly
interactive and instead of displaying
the same content for every user they
will display your specific data and
these kinds of web apps drive entire
businesses if you think of for example
your bank website or the real version of
airbnb and this list goes on and on if
you think of social media websites or
online games or anything that is highly
interactive and displays data that's
specific to you as the user you could
say they all exist on a tier sort of
above a static website because of the
amount of interactivity they have of
course we're not quite ready to recreate
an entire site like airbnb so we'll be
using this meme generator project to
drive forward the curriculum in this
section
in this project when the app first loads
it's going to reach out to an api and
get 100 of the most popular meme images
at that time and give the user the
ability to enter the text that shows up
on top the text that shows up on bottom
and also to click a button to randomly
choose a new meme image just like before
you can click the screenshot here to go
to the figma design file and again i
recommend you copy it to your draft so
if you click the arrow at the top
duplicate to your drafts and choose this
option it will put an editable copy in
your own figma drafts that you can use
as reference
in order to build this project we're
going to be learning about event
listeners and how we can add that
dynamic interactive aspect to our web
application we're going to spend a lot
of time learning about something called
state we'll officially cover conditional
rendering which you've already had a few
sneak peeks at so far we'll talk about
forms and how we can gather data from
the user and we'll learn about side
effects and how we can manage side
effects in react
once again we'll be starting off by
building some of the static components
of our page here so if you already feel
like you're a hundred percent good on
css in react you can skip the first
couple lessons where we're mostly just
doing some setup and styling for this
app however i do encourage you once
again if you haven't been practicing
your css inside of your react or
honestly even if you're feeling a little
bit hesitant on css in general not
specific to react then don't skip those
screencasts go through those lessons do
the challenges and that will be a great
way to get some additional practice on
those topics and set you up for success
with the rest of this project
so click the screenshot to open it in
figma copy it to your drafts and when
you're ready let's get started on this
section which i'm the most excited about
in this whole course
sometimes if i'm feeling overwhelmed by
a project like the meme generator here
where we haven't learned some of the
things we need to know in order to
complete it i will break the app down as
much as i can into pieces and then see
which of those pieces i actually can
create for example we've spent this
entire course so far learning how to
build static react sites and the truth
is there are static parts of this site
so the first one we're going to start
with is the header remember you can
click this screenshot in order to go to
the figma design which you can use to
determine the font sizes the spacing
this cool purple gradient here and so
forth so let's start out with that pause
the screencast and work on building the
header component
first i'll get the pieces into place i'm
going to create a separate components
folder although this app is probably
small enough that it's not really
necessary i'll just do it for practice
sake
i'll create a header.js file inside of
my components folder and i'll just spin
up a basic react component here
i'll do that little sanity check that i
like to do just to see that it's working
on the page
in my app.js i will import
my header
let's put everything here in a div since
i know that i'll have multiple things
here
okay my header component is showing up
next let's get the content on the screen
i know it's not just an h1 so i think
i'll surround this whole thing with a
header element
and i probably wouldn't call this an h1
because it's not really the main
headline of the page it's sort of in the
header itself
so let's maybe call it an h2 before that
i'm going to have an image
and i already know the source is going
to be my images troll face
and let's see it needs to be relative
like this
that's probably going to be bigger than
we want it to be but we'll fix that in
just a minute
and last of all we have this react
course project 3.
i can't really decide what it should be
let's just call it
maybe an h4 or something
i know that i'm going to style my header
so i'll go ahead and give it a class
name
we'll just say it's header
i'll hit save and go to my styles
usually with two dimensional layouts
like this in a single line i will revert
to flexbox so we'll say this is display
flex
we'll align everything to the center
from the design it looks like the height
is maybe about 65 pixels
that's making my image overflow a bit
we'll fix the image in just a minute but
i'm going to grab my background which is
from the design so i'm just going to
paste it directly from the design there
the color of the fonts and the text
should be white
and there probably should be a bit of
padding i think we have something like
15 on the top and bottom and 20 on the
left and right although it might just be
20 all around
we'll just call it 20 all around
then i will give some class names to the
other elements here
we have header image header title and
header project so we'll start with the
image
and we'll make sure that this fits
within the
boundaries of its parent by saying you
have a max height of one hundred percent
in the design it looks like there's also
some space about six pixels so i'll give
this margin right of six pixels
the header
title
it has a font size of about 20 pixels
and i can push my react course project 3
all the way to the right by giving my
title a margin right of auto
we can see that a little more readily if
i make this wider
oh and this still says header component
let's update that
to say meme generator
and let's lastly style our
project text
that has a fairly small font size we'll
say that's about 12 pixels
and i think the weight is maybe
different let's give it a font weight
500
and yeah that does change it so we'll
leave that on there
and you know what one thing i'm trying
to get better at is using rams for my
font size instead
20 pixels over 16 pixels equates to
about 1.25 rim and 12 pixels
over 16 is about 0.75 rim well it's
exactly 0.75 rim
awesome work this is a great start the
next thing we can do is attack this form
here we've got two inputs and a button
we're not quite ready to make them
functional but we can at least get them
on the page so let's do that in the next
challenge
the next piece of our project that we
can bite off is the form that we have
right here with the two inputs and the
button so that's your challenge for this
screencast don't worry at all about
creating any functionality for it i've
outlined exactly the steps that i want
you to do here we're going to create a
component called meme inside that meme
component we'll render a styled form
which will have our two inputs and our
button pause the screencast and work on
this challenge
let's actually work backwards this time
i'm going to pretend that i already have
a meme component created so i'll just
import it
and render it
since i'm already here in this file
and then i'll actually create it so
inside of components i'll create meme.js
and set up my component
now i didn't talk about this
specifically but i happen to know ahead
of time that i'm going to put both my
form and the actual meme image and this
text all into this same component the
reason i want to do that has to do with
when we start talking about state and
where state needs to live so in an
effort to reduce complexity i'm just
going to put everything in the one
component the reason i mention that is
because i already know ahead of time
that i'm going to use a main element to
surround everything else on my app if
you didn't do that it's completely okay
but this inside of here is where i'm
gonna put my form
i already know that my form has two
inputs
and a button
i've already got my button text copied
and i'll paste it here since it's got
the little emoji there
i also know that i want these to be a
type of text so i'll add the type text
there let's hit save see what we're
working with okay pretty generic styling
let's give this some love in the css
i think the way that i would like to lay
this out is using grid i could probably
use flexbox as well but what i'll do is
make a two column and two row grid and
lay the elements out there inside
the grid will be the form so i'll make
that the grid container i'll give this a
class name
of form
and while i'm here i think i'll give
these their own class names as well i'm
going to put these on their own lines
we'll say these are form inputs
and i'll give my button a class name
form button
i guess i can also give my inputs some
placeholder text so we'll add
top text and bottom text
it's a little more helpful now in our
css let's select our form
we'll change it to display grid
and then set up a grid template that has
two 40 pixel rows
and then evenly divide the columns with
fraction units we'll have two columns
one fr each
since i have three items it's putting
the first item filling up one column the
next item filling up the next column and
then the third item only filling up one
column the inputs look essentially the
way that i want them to but i want the
button to span the whole thing so i'll
select my form button
and tell it that its grid column
will go from the very beginning to the
very end awesome it looks like in the
design there's a little bit of a gap i
can use the gap property to spread
things out a little bit then of course
everything is butting up against the
edges of my page here i only am going to
have one main element so i'm just going
to select the main element directly
and let's give it a padding i think of
about 36 pixels is what the design shows
one thing you might notice is that the
placeholder text and the button text are
not taking on our carla font family for
whatever reason inputs and buttons
inside of forms tend not to do that so
i will specifically
add that in my form button
and i will also select my form inputs
and i think i'll put this above my form
button since my inputs are above
my button in the markup
and i'll give that the font family as
well
let's also get some border radiuses here
i've got
both of these as having a border radius
of 5 pixels
my inputs have a border of
1 pixel
solid and then this color that i'm
copying from the design
and oh we need our hash mark there
there's a fun property called text
indent that i learned about here i can
make it so that my placeholder text and
my
actual input text will bump in a little
bit or have a little bit of an indent
we'll just give it a 5 pixel indent and
i just noticed that these styles are not
applying uh that's oh that's because i
need this to say form input not form
inputs
okay that's working now let me comment
this out yeah you can see what the text
invent is doing
okay my button needs a lot of help i'm
going to take the background from the
design in the figma file that also gives
us that gradient of purple i need to
change the color to white
i'm going to remove the border i always
like my buttons to have a cursor of
pointer
and awesome that's looking great it
looks very much like our design now at
this point i probably could separately
create this image with the text sitting
on top but i think it's high time that
we jump into actually understanding what
it is we need to learn in order to do
the functional parts of this application
including clicking the button and typing
in our text
so in the next cast we'll talk about
what that will actually take
the primary thing that sets apart a
static website like we've been building
so far with web applications is the
ability for the user to actually
interact with our page and in order for
a user to interact with our page we have
to be listening for different events on
that page and then reacting when those
events happen let's get a quick overview
as to how this app will work as soon as
the app loads for the very first time
it's immediately going to make a call to
an api called imageflip which will
return to us an array of 100 meme images
that are the most popular at that time
then clicking the get a new meme image
button will simply randomly choose one
of those 100 images in the array that
got returned to us and as you've
probably figured out typing into the
left input box will give us our top text
and typing into the right input box will
give us our bottom text now there's a
lot in there that we need to break down
before it becomes overwhelming so let's
start off really easy the first thing
we'll do is learn how to add an event
listener to our button so that we can
run some kind of logic when the button's
clicked and we'll start that in the next
lesson
the primary thing that separates a
static website from a web application is
the ability for the user to interact
with what they see on the screen by now
you should have built plenty of
javascript applications that used events
and event listeners to allow the user to
interact with your application so this
topic shouldn't really be new to you you
should already be familiar probably with
two different ways that in a vanilla
javascript application you can add
events to your program first of all
there's the dot add event listener which
you probably are already familiar with
if you were adding a click event you
would then
provide a function and inside this
function you put the code of whatever
should happen when the element that
you're listening for an event on gets
clicked alternatively there's a way in
html where you would essentially put on
click and set that equal to the name of
a function
followed by parentheses this second way
is going to be much more similar to how
we actually accomplish adding event
listeners to items in react for example
let's start with our button here we're
going to make it so that when we click
the button something will log to the
console in react all i need to do is on
my button add an on click and you'll
notice that i used a capital c and
that's because we are accessing the dom
properties of the object that's being
created here as a reminder what react is
doing is it's taking this jsx element
that it sees which in the end returns a
plain javascript object describing the
dom element that should be created by
react and whatever properties or
attributes we add here inside the jsx
are directly accessing the equivalent
properties in javascript if i were to
select this button in javascript using
document.getelementbyid or something
like that i would have a dom element
that has a property called on click with
a capital c and this camel casing is the
standard throughout all of our
javascript elements so all that means is
that instead of using the lowercase c
like you might be used to doing in html
we're going to have camel cased
properties everywhere so on click maybe
on mouse over
or on mouse enter and so forth let me
put this back to on click and we'll see
the other difference here
now instead of setting this equal to a
string which has a function name because
i'm here in javascript i can actually
just use a set of curly braces and then
put a function directly here inside of
my on click now personally i'm not a big
fan of stuffing my functions inside of
my markup here if i can avoid it so what
i usually do is above my return but
still inside my component i'll define
another function up here and say
handle click maybe because this is the
click event handler
then i can say console.log
i was clicked
let me get rid of this and i'm gonna
give you a mini challenge
okay pause the screencast and make it so
that clicking the button will run our
handle click function
a few of you may have been tricked into
thinking that you can put handle click
with a set of parentheses and well let
me refresh and see what happens
notice that as soon as i ran this code
it ran my handleclick function i don't
want this set of parentheses here
because that will run this function as
soon as the program reads this line of
code instead i'm passing the function as
a value
so that react can add that function as
the event handler in case a click ever
happens on this button so without the
parentheses there i can hit refresh
clean this up i can hit click me and
then that's when our click event handler
runs the react documentation has a full
list of all of the events that it
supports i've included here a screenshot
that you can click from the react
documentation this will take you
specifically to the mouse events i've
personally found that mouse events
probably make up a good 95 percent of
the events that i listen for in any
program i write and you'll probably need
to use this as a guide for the challenge
that we will do right now
your challenge is to log something to
the console whenever the mouse hovers
over the image i added some css to
darken the image just so it was a little
more obvious when the mouse was actually
hovering over the image again feel free
to use this as your reference pause the
screencast and work on this challenge
there's a couple different events that
should work just fine for this challenge
we have on mouse enter which will run
anytime the mouse enters an item that
we're listening for an event on and
there's also on mouse over which
essentially does the same thing it just
has a slight difference dealing with
children elements right now we don't
have any children elements of our image
so it really wouldn't matter which one
we use first let me create a function
that will run when we are hovering over
the image maybe i'll say handle on mouse
over
and we'll console log
mouse over
and then i can simply add to my image
let's put it after the source will say
on
mouse over
equals and then curly braces because i'm
going to put the name of our handle
mouse over function pull these onto
separate lines to make sure that we can
see them well hit save
and now when i hover over the image or
rather when there's a mouse over event
on the image it runs our javascript code
and we get that console log displaying
down there feel free to poke around the
documentation event listeners can be
kind of fun especially when there's a
bunch that you may not have heard of
just seeing how they work can be a fun
thing to play with understanding this is
going to be assumed from here on because
you already should be a little bit
familiar with events and event listeners
at this point fortunately doing it in
react is actually fairly straightforward
and now this sets us up for one of the
coolest parts of react and we're going
to jump into that next
let's apply what we just learned about
event listeners to our meme generator
project ultimately what we'll be doing
is making an api call as soon as our
component loads and getting data from an
api that includes 100 of the most
popular meme images right now but we
haven't quite yet learned everything we
need in order to make that work so for
now what i've done is i made the api
requests and i just saved the data that
came back here in memesdata.js
you can see we have the object it's got
a data property that has a memes
property and that is an array of 100
items each one of those items is an
object that has a url property so you're
going to have to do a little bit of
digging into this memes data object but
your challenge is to make it so that
when we click the button it will
randomly choose one of those urls and
just log it to the console for now don't
worry about displaying the image yet one
modification i made to our markup here
is i changed our form element into a div
element long story short when you have a
button inside of a form it actually
submits that form and tends to refresh
the page unless you stop it but i
realized that there's actually no reason
for this to be collected together in a
form because ultimately this button does
its own thing by getting a new image it
does not take these inputs and submit
them somewhere so in this case i feel
like it's okay to have our inputs
floating outside of a form and that way
it means that when we click our button
it doesn't refresh our page because it's
not trying to submit a form okay so the
challenge is to get a random image from
the memes data array which i've already
imported for you you'll get that anytime
this new meme image button is clicked
for now just log the url of that new
image to the console if you're feeling
hazy on how to get a random item from an
array you'll probably want to turn to
google but i know that you'll be able to
do it pause the screencast work on this
challenge
let's start by hooking up our button i'm
going to add an on click event listener
and when the button is clicked i will
run a function that says get meme image
i haven't yet created that so let's
create that function get meme image for
now i'll just have it console.log
clicked to make sure that everything is
hooked up correctly
hit save click the button clicked okay
good now if we look closely at memes
data
it's an object
there's the object it has a data
property which has a memes property so i
need memes data dot
and that's my array i think i'll
simplify that by simply saying
const memes
array
equals
means data dot theta dot memes
and then i will generate a random number
so i'll say
random number
and
i can use math.floor math.random times
the length of my array so that's memes
array dot length
this random number should get me a
random index of my memes array and that
indexed item will be an object with a
url property
so
let's actually just console.log random
number and see how we're doing so far
16 50 92. okay i wanted to see a high
number to make sure that it was going up
to a hundred i probably don't need to
click this until i see 100 or actually i
think it would be 99 so i can get my
image object or actually i can just do
it all in one i'll say const url
equals and then i'll index into memes
array at the index of random number
this is my object with a url property
so i'll just save that as url so it's
nice and short or if we wanted to do
some object destructuring i could just
say get me the url property from this
memes array i don't want to conflate a
few things here so i'll just keep it
straightforward like this
and then we'll just console.log the url
of course i could do probably most of
this in a single line but i find that
sometimes separating it out makes it a
lot easier for other people to read
we'll hit save and i guess i have no way
to ensure that these are in the correct
index but i can't see why they wouldn't
be so this is awesome we're getting
random images every time we click our
button at this point we are a little bit
blocked and i'll show you why if i
create let's say a paragraph
down here
and i try to stick my url in there well
first of all i have a problem because my
url is only declared inside of this
function and so this is not going to
know what i'm talking about if i hit
refresh it's going to say it doesn't
know what url is essentially
so you might think well let's declare
url outside of the function
you could say let url
and then just set url equal to this and
console.log url let me hit save and now
at least url is well of course my
styling is all messed up because my
paragraph is let's put this let's put
this outside here so we have that above
click new meme image okay well we set
url equal to the new meme image right
here however my ui did not update this
has everything to do with the way that
react looks at variables and decides
when it should update the ui or the user
interface and spoiler alert it doesn't
do that by just looking at every
variable that we declare inside of our
component in the next cast we're going
to dive a little deeper into this
conundrum that we have and start
figuring out how we can make it so that
we can update a variable that will then
replace what we have on the screen with
the new value of that variable
at this point in our journey we have
mostly been dealing with static websites
in the previous section we showed how we
can take data that we pull from for
example an api we were just using a
little javascript local data file to
mimic pulling from an api and then we
mapped over that array of data to
display items on the screen however in
order to interact with those items on
the screen we are still missing
something i want to demonstrate what i
mean but before we do that just in case
it's been a little while let's get our
hands in the keyboard with a quick
challenge
i have here just a locally defined array
with two strings in a thing one and
thing two i want you to map over the
things array generate a paragraph
element for every item in the array and
then render those items below the button
right here this challenge harkens back
to the last section where we learned
about dot map and how to take an array
of data and turn it into elements on the
page so pause the screencast and work on
this challenge
okay what i'll do is create a new
variable called maybe things elements
and i will set that equal to the array
that comes back when i run dot map on my
original things array
we'll look at each thing in this array
which is just a string
and we'll return a jsx wrapped
version of that string so really just a
paragraph element in jsx
where what we insert on the inside is
the text of that thing thing is just a
string so it's fine if i just put it
inside of my paragraph like that
then things elements is an array of
paragraph elements and i can just put
that
inside my curly braces here
hit refresh and now i have thing one and
thing two i did get that warning about
key
so i should probably just add a key prop
here and
every one of these strings will be
unique we'll see why in just a second so
i'm just going to say that thing is the
key and that should set them apart and
get rid of my warning there cool
well this is great but we've got this
button that doesn't currently do
anything let me set up another quick
challenge for you the concept is going
to be that you click the add item button
and it adds another thing to our things
array
namely thing three and then you click it
again it'll be thing four and so forth
i'll type up this challenge now
okay your challenge is to add an event
listener to our button so that when it
gets clicked it adds another thing to
our things array in your event listener
you can use
thingsarray.length plus one to determine
what number should get added to the next
item in this array and it also will be a
good idea to make sure that at the very
end of that event listener that runs
when you click the button that you
console log your things array and the
reason is because
spoiler the page is not going to update
when you add new things to the array i
decided it would be important to let you
know this little fact ahead of time so
that you weren't pulling your hair out
trying to figure out why the heck things
weren't changing on the page
so pause the screencast and work on this
challenge
well let's create a function called
we could call it handleclick or i could
say add item maybe
and add item is going to well first
let's just console.log things array
and set up our on click
add item
so that we can see that it's working
okay so it's logging thing one and thing
two the static array that we have there
so i probably could add the whole thing
in one step just using things read out
push i'm going to determine what the
text of the new thing is first so let's
say
new thing text
and that's going to be i'm going to use
a template literal so i can say thing
space
and then insert some javascript where i
say things
array dot length plus one
and then i can say things array dot push
new thing text
and then of course i'm going to log the
things array after i push the new item
let me open the console so we can see
that a little more clearly i'll hit save
add item okay oh not a number of course
because i spelled length run let's try
that again add item thing three thing
four thing five great well our array is
changing but of course what we see on
the screen is not and this brings us to
our conundrum at this point react is not
looking at local arrays that are just
saved within a component to determine
whether or not something should get
re-rendered or rather if the return here
should run again with an updated value
for things elements actually maybe more
specifically i'm determining my things
elements way up here at the top back
when things array is just two items long
and then it's sort of cementing this
thing's elements into its memory and no
matter what i do to change things array
it's not going to automatically change
things elements in my early days i
thought maybe if i put this below add
item or something like that it might
make a difference but that's not going
to change the fact that this line of
code will only run one time and that's
the very first time the app component
gets rendered right here let me clean
this up real quick now one thing that
might be tempting to do is inside of our
add item function to say well let's not
just update our array let's actually
select the elements on the screen using
document.getelementbyid
and finding out where the container for
these items is and then pushing a new
paragraph element to that list and the
truth is when you're just using plain
javascript that's essentially what you
have to do but if you think back to one
of our earlier sections we talked about
how react is declarative and this is one
of the major benefits of having a
declarative library like react it makes
it so that all we really need to do is
update our data and react will
automatically well react to that change
and update our ui to display what has
changed in the data all we need to be in
charge of is making sure that the data
updates correctly and react will handle
the rest
however for that to work we need to
access something called react state and
state will allow us to sort of hook into
the component and make it so that
whenever we update our state which is
really just values that we're saving
inside of this component it makes it so
react will update the user interface
based on any changes that happen to
those values that are being saved in
state and truthfully if you think of
pretty much any website that you
interact with if it were made in react
any kind of interaction you had would
change the state the first thing that
comes to mind is maybe i don't know a
playlist or a recipe where you hit the
little heart icon or maybe a bookmark
icon and it fills it in and likely sends
a message out to a database that updates
the fact that you have liked a recipe or
a song or maybe it's an accordion or a
carousel where you click something and
an image shifts over or a portion of the
page expand so you can read more
information any of those interactions in
react are going to be updating state
which then makes it so that react can
update the user interface to respond to
however you interact with the page
so now let me update this using state
and you can see how it will actually
start to work again the way we
originally expected obviously at this
point some of this will look a little
bit foreign and that's totally okay
we're going to dive deep into
understanding how to actually write this
ourselves but you can see that not that
much changed in my actual code but
suddenly i have an app that's working
the way that i expected the example is a
little bit contrived obviously but
hopefully you can see the exciting world
of state and react that we're
approaching and start to imagine some of
the cool things that it's going to allow
us to do so buckle up and get ready to
jump into react state
one thing i've learned over my years of
teaching react is that one of the major
points of confusion for students when
they're first learning react is
understanding the difference between
props which you have already learned and
state which we are about to learn so
let's take some time and clarify the
differences between the two and when you
would want to use one over the other and
the first thing we'll do is look at
props we've seen how we can implement
props in practice but let's take a
second to actually talk about them when
we refer to props we are referring to
the properties that we are passing into
a component in order for that component
to work correctly this is similar to how
a function can receive parameters
quote-unquote from above
just like a function that receives
parameters a component that receives
props is not allowed to modify those
props or in other words those props are
called immutable let's first take a look
at a regular function
let's say i define a function that says
add to numbers
and i pass in my parameters of a and b
as i'm writing the logic of this
function i'm going to assume that this
function will be past a and b
of course i could always do some kind of
check that says if there's no such thing
as a or if a is equal to undefined then
throw some kind of error that says you
need to provide both a and b but other
than that inside of the body of the
function i can just assume that i have a
variable a which is a parameter that has
been passed to this function and i can
assume that i have a parameter b another
parameter passed to this function and
that's what i mean by being passed from
above when we actually use this function
we'll say add two numbers i'll provide
my actual values that i want to
represent the parameters a and b
and my function can then do its job
the main point that i want to come
across here however is that inside the
body of this function it wouldn't make a
whole lot of sense for me to modify or
mutate these parameters for example i
wouldn't want to say forget what you
just gave me for a i'm going to set it
equal to 42. naturally this should feel
wrong to you because essentially we're
ignoring anything that is passed in as
the first parameter here and just
setting it equal to 42. technically this
probably works if i were to console.log
the result from add two numbers
one and two of course i would expect it
to be 3 but
we'll see that it's actually 44 and
that's because we've overwritten a to be
something different similarly in react i
would never want to have a component
let's say a nav bar that takes props but
then automatically sets props dot i
don't know let's say cover
image
equal to
something else
this is a huge red flag you would never
want to set props dot anything or props
itself equal to anything different
because incoming props should be
immutable and they should never change
manually or maybe more specifically
those props should never change from
within the body of our component itself
now that's not to say that when i have
an instance of my navbar that i can't
provide a cover image that changes let's
say it starts out as some image one and
then i don't know maybe there's a button
on the screen when the user clicks that
button i want my navbar's cover image to
update to some other image maybe this is
a little convoluted because i'm not
really using images here but the point
is i can change the values that i pass
to my component that's fine that's
something i'm allowed to do and as we
jump into state we're going to see why
that's even useful but from within the
body of the function i should never ever
change my props in the same way that i
would never want to change the
parameters being passed to my function
another way to think about props here we
read that they are the properties being
passed into a component in order for it
to work correctly if it helps you could
think of it as the properties being
passed to a component in order to
configure it as we saw in our last
section project we passed props to our
card component in order for that card to
be reusable and configure it to display
the correct image the correct price the
correct stats like the review count and
so forth and oftentimes you'll find
components that do more than just take
in the data that should just be
displayed as a part of the component
sometimes they will receive
configuration objects or properties
let's say for example off the top of my
head if we had a component that we
wanted to display either in light mode
or dark mode well then maybe i would
have a
dark mode property that i could set to
true in this case i'm not necessarily
displaying the literal text true for
dark mode or the text dark mode is
activated or anything like that but
instead this is a property that is
configuring my navbar in order for it to
act and display correctly okay i might
be beating a dead horse here so let's
move on and we're going to see how the
use of state will differ from our usage
of
props if props are data that a component
is receiving from above and shouldn't be
changing state on the other hand are
values that are defined within a
component and essentially should be
changing so as we see here state refers
to any values that are managed by the
component itself kind of like a function
that declares its own variables from
within that function long story short
anytime your component has changing
values that should be saved and
displayed you're most likely going to be
using state we'll jump into what this
looks like in react in a second but i
think it might be helpful to see how
this compares in a vanilla javascript
example kind of like we did with our add
two numbers and having what we can
equate to props being passed in as these
parameters and how we shouldn't be
changing them from within the definition
of this function itself
in order to create an equivalent in
vanilla javascript of our concept of
state let me write out a challenge for
you
let's say we have a function called
greeting it takes a name as a parameter
and what it should return is a string
like good afternoon and then followed by
the name of course afternoon will change
depending on the current time of day as
you can read from the challenge
description up there at this point this
is more of a vanilla javascript
algorithm challenge for you but i think
it's good to incorporate those into our
react course here and maybe just so that
i'm not making you chase google a whole
bunch right now i'm going to give you a
couple hints here
so you can get the current time of day
by following these two lines of code
essentially first you create a new date
object in javascript and then you use
that date to get the current number of
hours these hours are zero index so 12
am is zero 11 pm is 23 and just to be
clear i have included the 11 59 459 and
everything up here just to be clear what
hours should be included in morning this
one's kind of funny because i don't know
that i would ever say good night to
someone at 3 59 a.m but whatever my
point is you won't need to get the
minutes here you can just use the hours
like i've shown you here pause the
screencast see if you can complete this
challenge then we're going to bring the
concepts back into understanding state
and react
now i won't spend a bunch of time
talking about the logic of this we'll
just put in a solution here and then
talk about how this equates to state and
react i have the number of hours now if
i console log those hours
it's 12 pm my time so my answer should
say 12 there yep
so i will type out some logic that i
think will just kind of intuitively make
sense
the first thing i'll do is just declare
a changeable value here time of day and
then depending on the current number of
hours i will change the string time of
day to be either morning afternoon
evening or night just like i talked
about in the challenge and now that i
have a time of day value i can simply
return the string and i'll use some
interpolation here we'll say good and
then we'll stick in the time of day
comma and then i'll use the value for
name that i'm receiving as the parameter
to greeting exclamation point and let's
go ahead and see if this works
again it's about 12 o'clock my time
so i should when i oh i'll need to
console log this
the value that gets returned
good afternoon bob okay now the point
here is my function is receiving a
parameter this parameter is not
something that i will want to change in
the way of saying name equals something
different
because that would just be a well a kind
of a strange thing to do when you are
expecting the outside user of this
function to provide you the name
similarly in react we are not going to
take any props and then just change them
which is what we talked about in the
last screencast however there are
definitely reasons for us to within our
own function create values that we can
either use or even change like our let
time of day here in react values that
are created by the function or the
component itself are usually handled
with state okay i think that's more than
enough of the conceptual difference
between props and state at this point
it's probably best for us to just get
our hands dirty and start actually
seeing how we can implement state and
react and then as we build our section
project we will get much better exposure
into how state and props will work
together and how they are different from
each other as well
it's time for another quiz this one's
going to specifically be looking at the
difference between props and state so as
always read through these questions
click into the editor type down your
answers and when you're satisfied with
your answers click play and we'll go
through the quiz together
on a higher level the concept of state
is sort of like saying the way things
currently are here in the united states
the president gives a yearly address
called the state of the union growing up
that always confused me because the
united states is made up of 50 states
and i thought it had something to do
with that but no it means the way that
things currently are
in react state refers to values that a
component can maintain between render
cycles
this will make more sense when we get
into the syntax of it but let me type
down a more concise answer to this
question
the concept of state is essentially a
way for react to remember some saved
values from inside of a component this
is similar to declaring variables within
a component but there are a few added
bonuses to it which we're going to get
to later
so when would you use props instead of
state in react
i think the easiest way to think about
this is to compare it to regular
javascript functions
props are like passing parameters into a
function that the function then uses to
help it determine the output what gets
returned so in react you would want to
use props anytime you need to pass data
into a component so that that component
can use that data to determine what
should get displayed on the screen
in some cases the data that we pass in
will directly be data that is displayed
like in the instance of text but
sometimes it will be data that's really
just meant to so to speak configure the
component so that the component can use
it to determine how something gets
displayed
okay so when would you want to use state
instead of props
continuing with our function analogy
state is kind of like when inside of the
body of a function you declare new
variables
and you use those new variables to help
you accomplish some task inside of the
function
in react you would use state anytime you
needed a component to maintain its own
values as we mentioned earlier it's
slightly different than just declaring a
regular variable we're going to see the
syntax of it later and how it differs
but for now that should be a sufficient
answer to this question
so you would use state anytime you want
a component to maintain some values from
within that component and by the way
also remember those values even when
react needs to re-render the component
again we're going to see that much more
in detail a little bit later and a
little bit out of left field what does
the term immutable mean and then our
props immutable and is state immutable
immutable technically means unchanging
the reason i bring this up is because we
learned that props are immutable we
should not ever change props from within
the component that's receiving props
doing so essentially defeats the entire
purpose of props think of it like a
function that receives a parameter but
then just decides to change the value of
those parameters to something different
it pretty much invalidates the whole
purpose of passing parameters into a
function so props are
immutable
in this case i don't think props are
literally immutable you can try to set
them equal to something else and i don't
believe it will crash your program
although it may throw a warning but
maybe a better way to describe it is
saying that you should not change props
and therefore they are immutable
state on the other hand is not immutable
or in other words state is mutable the
purpose of declaring state in a
component is because you do plan on
changing state
okay we're done with the quiz nice work
when you're ready let's keep moving
forward
we saw in an earlier lesson how it's not
going to work for us at least in react
to just declare regular variables like
let's say state is equal to yes and
expect react to re-render our component
if for some reason that state ever
changed if you recall we had an array of
items and we had a button that allowed
us to push new elements to that array
but whenever we did that it didn't
actually update our page and that's
because react doesn't watch for local
variable changes so the first thing
we'll do is learn how to actually
declare state inside of our component
and in the next cast we'll talk more
about how to actually change that state
as a part of the react library there is
a method called use state and use state
is one of many what are called hooks in
react there's a little bit of history as
to why it's called hooks we're probably
just not going to worry too much about
it right now but the point is i can
declare some state by simply calling
react dot use state now another way you
might oftentimes see this is people will
destructure it directly in the import
statement they'll grab the use state
method from react as well and then they
can just use use state in fact i would
suppose this is the more common way you
will usually see it happen however just
for perfect clarity and for it to be
very clear that use date is part of the
react library i'm actually going to use
react dot use state because i do find
that it makes it a lot more clear where
this use state method is coming from
let's go ahead and see what comes back
we'll say const result equals
react.ustate and then we'll console.log
result just to see what actually comes
back by calling react.usestate
i'll open the console hit save
and look at that okay so that's
interesting we get an arrayback and the
array has its first value as undefined
and its second value well in scrim but
it says f parentheses that just means
that it's a function now let's see what
happens when i put something inside the
parentheses let's say the string hello
i'll hit save
and now the first value of my array is
the string hello so whatever i put
inside of my parentheses when i'm
calling use state is going to be the
default value for the state variable
that i want to save
okay so now that leads me to a little
mini challenge that will require you to
think a little bit critically i'm going
to type the challenge out now
okay your job is to replace this yes
with a string yes that isn't just hard
coded inside but rather is created by
using react.usestate remember what we
get back by calling react.usestate is
not just the string hello it's actually
an array so let that guide you as you
work this challenge pause the screencast
and work on this now
the first thing i can do is change hello
to yes
and then my result is an array and the
index of zero should be let me just log
this should be my string yes
so i could replace this yes with a set
of curly braces because i need to jump
into javascript and then i can say
result at the index of zero i'll hit
save and we get yes the exact same way
we had it before but now if i were to
change this to no which is not true
state is important to know awesome our
page actually updates with the state
that we had created with react.ustate
change this back to yes because it
certainly is important to know okay well
there's a couple of problems we have
first of all this is kind of clunky to
say result at the index of zero in the
next screencast we're going to learn a
little bit more about what we can do
with this array and then we will bring
out the real power of using state by
allowing the user to interact with our
page and change state themselves so when
you're ready let's jump into those
topics
as we saw what we get back by calling
react.usestate is an array where the
first item is the value of the state
that we are hoping to save kind of like
initializing a variable inside of our
component and the second item of that
array is a function so we saw how we
could use result at the index of zero to
get our value however there's actually a
much smoother way to deal with this and
this requires us to use array
destructuring since react.ustate returns
an array what we can do is actually
destructure that array immediately upon
receiving it as a variable and then we
can provide two values and let me just
put funk because we know the second
value is a function
now in this case if i rerun console.log
result what we see is that we have
pulled out the first item in the
resulting array of react.ustate and
destructured it into its own variable
called result what's nice about using
array destructuring is that we get to
call this whatever we
want
if this were object destructuring we
would have to use the property name of
the object that comes back by calling
react.usedate but because they return an
array we can call it whatever we want so
if i console.log whatever we want we get
the same thing yes
oh and now my result down here is broken
so if i change that to whatever we want
we get back to the way we were now don't
use silly names like whatever we want
instead let's say maybe is important
we'll choose a variable name that makes
a lot of sense for what the value is
that we're trying to keep track of
and that's the concept of using array d
structuring in order to more smoothly
get values from react.ustate in the next
screencast let's talk more about this
function here
let's take a look now at the function
that we receive here when we destructure
the array that comes back from
react.usestate
normally if we had a variable where we
were saving this if we just said
something like let is important
equal
yes
then we already know we could simply say
is important equals something different
like no however when we're working with
state we can't simply say is important
equals something different
instead we are given a function that
allows us to make these changes so that
react can handle those changes
accordingly
let me delete these lines here and let's
take a look at this function now
normally we wouldn't just call this func
so let's give this a more meaningful
name the convention that you'll often
times see is set and then the rest of
the variable that we called our state so
set is important in this case i need a
capital i to make my camel casing
correct and this set is important is a
function that i can run and whatever
value i provide to it is going to be the
new version of state now of course
running this function immediately after
generating state is kind of silly in
fact i'm not even certain that it would
work instead we would normally want to
set or change the state whenever
something specific happens on the page
so let me type up a challenge so we can
do something like that
okay just to avoid confusion i created
the actual function body for you but
your challenge is to have this function
run this line of code and then to set up
an event listener on this div so that it
runs handleclick whenever anywhere
inside this circle gets clicked
pause the screencast and work on this
challenge
well simply enough i can copy this line
of code put it in there and then i need
to set up an event listener here so i'll
say on click again capital c
we will run our handle click function
hit refresh
and when i click my button here awesome
okay notice that as soon as i clicked it
changed from yes to no what happened is
we took the function that we were given
when we called react.ustate this
function's job is to give us the ability
to change state if we wanted to
and we used it in the most simple way
possible which is to simply provide a
new version of state as soon as this
line gets called which of course happens
as soon as we click our div here then
set is important gets called and the
state changes to no and well at this
point we've kind of hit a dead end
because obviously this is incorrect
state is very important to know but
notice that if i click this again and
again well nothing is changing and
that's because every time i click it it
immediately sets it to no
in the next screencast let's work on a
challenge that will help get your hands
on the keyboard practicing using state
all right here we have something that's
a little more dynamic the idea is we
will create a little counter when i hit
plus this number should go up when i hit
minus this number should go down to
start us off and to get your hands on
the keyboard i'm going to have you
complete this challenge where you're
going to set up state to track our
current count and our initial value is
going to be zero pause the screencast
and see if you can complete this
challenge
to create new state we simply use react
dot use state
and we can provide the initial value of
zero
and then we need to essentially catch
what this returns in some variables
it's an array and because what we get is
an array and i can destructure it that
means i can call it whatever i want
in the first index i receive the value
which i'll call the count and by
convention i will call my setter
function setcount this is the function
that when i call it will allow me to
update the state here one last thing
that i didn't specifically say to do and
wouldn't be very obvious unless i did is
to use this count value to replace our
zero here
now at this point nothing is going to
look like it has changed i still don't
have the ability to
raise or lower this number
now let me build up to the next section
by updating our challenge
okay your challenge is to create a
function that's called add that runs
whenever the plus button is clicked this
is just practice on event listeners in
general for now you can just have it
console log the string add or something
along those lines a good rule of thumb
to use is to declare these functions
inside of your component so instead of
going up here outside of your component
and creating your function called add
it's better to declare that function
right here inside of your component
pause the screencast and work on this
part of the challenge
okay let's declare a new function called
add
and for now we'll just console.log add
and let's see here is my plus button so
i will add an on click
of add
and now i should click this button and
get my console logging ad awesome
okay at this point we're running into an
issue and that is how we can update our
count what we most recently saw is that
i could say set count and then provide
some kind of immediate hard-coded value
here however that doesn't really help us
because even if i provide a 1
if i run this code it will work notice
that when i click the add button it sets
the count to one therefore it re-renders
our app and changes the zero to one
however of course if i hit plus again
and again and again it's just constantly
setting it to one and it doesn't really
accomplish what we want so i want you to
think critically i'm going to update our
challenge
i want you to see if you can think of a
way so that clicking the plus button
will increase our number by one every
time and display it correctly on the
screen obviously hard coding one here is
not going to work pause the screencast
and see if you can figure out this
challenge
hopefully you were able to figure out
that we do have access to our current
count and so i can just say i want you
to set the count equal to
whatever the current count is plus one
let me hit save we'll see that this is
working okay that's awesome but i wanted
to use this as a chance to show you a
common misconception or fallacy that
beginners in react tend to fall into and
that is trying to do something like
count plus plus or even plus plus count
if you're familiar with the differences
between those two let's look at count
plus plus for example
in the philosophy of react something
like count plus plus is strictly
forbidden and that's because we never
want to modify state directly what i
mean by that is this count plus plus is
a shorthand for count equals count plus
one and in this case using count equals
is just a big no-no you will never ever
do that when you're modifying state the
entire reason that we have this set
count function is so that we can simply
provide a new updated value but we will
never ever want to run an equal sign
after our state value
so let me put this back to count plus
one
we'll see that this is working and now i
want to update our challenge to finish
off the basic portion of this app
okay your task is to add functionality
to the minus button now of course
clicking the minus button should
decrease our number by one pause the
lesson and see if you can figure this
one out
all we need to do is to create a
subtract function instead so i'll create
a new function called subtract
of course this one should take count and
subtract one
and then we need to add our on click
handler for the minus button so that
will go right here
subtract
and once i hit save we should be able to
go backwards as well
awesome great work however i do have a
little bit of bad news although we were
able to use our count state value here
in order to help us determine the new
count it turns out we're not actually
following best practices when it comes
to using this state value here so in the
next screencast we're going to see
another way that we can use the
setcountsetter function to update our
state value
although currently it's technically
working for us to use our current state
value in order to determine the new
state value when we're setting our count
it turns out there's actually a better
way to use set count in this case
whenever we need to use our old version
of state to determine our new version of
state
we've seen how we can simply provide a
new value to our setter function however
there's another way that we can use this
setter function and that is to provide a
callback function inside
when we provide a callback function as
the parameter to our setter function
this function needs to return the new
value that we want state to be if we
essentially wanted to recreate what we
did by passing a simple value to our
setcount function we could just have our
callback function here return count plus
one however this is where the best
practices comes in
anytime we need to use our old state
value to determine a new state value if
we provide this function react will pass
this function the old value as the
parameter here what we can do is then
take this old value and use that as our
reference to what count was at the time
that this function was called this might
be really confusing at this point it
would require us to jump a little bit
deeper into how react handles state
changes and re-renders to truly
understand why this is best practice for
now i think it's going to be enough to
simply say if you ever need to use the
old value of state in order to determine
the new value of state you should just
always plan to pass a function to set
count
this might be a little disheartening
because this already looks way more
complicated than what we had here
fortunately if we use arrow functions we
can simplify this quite a bit i can just
say given the old value
return old value plus one usually what
i'll do is use the prefix of prev and
then use my state value so i'll say
preview count as in previous count so
this is the convention you'll usually
see me using whenever i'm using a
callback function as my parameter to set
count because that was a little bit
confusing i'm going to type this out as
a note so that maybe those of you who
are more visual learners will be able to
comprehend it a little better
so again if you ever need the old value
of state to help you determine the new
value of state or in other words if the
new value of state depends on knowing
what the old value of state was you
should always pass a callback function
to your state setter function instead of
using the state directly like we're
doing down here
then this callback function will receive
a previous version or the old version of
the state value which you can then use
to determine the new state value with
that said let's do a quick challenge
okay your challenge is to update our
subtract function to use this callback
function as the state setter instead of
what we currently have pause the
screencast and update our subtract
function
fortunately with arrow functions this is
still very concise i can say pre-count
arrow
pre-count -1 and just for demonstration
when i refresh this you can see
everything is working exactly the way as
it was you're obviously more than
welcome if you're really curious to deep
dive into this do a bunch of google and
youtube searches to truly understand why
this is better frankly i would say
probably 90 of the time you would never
notice the difference between what we
used to have and what we currently have
however it is generally accepted as best
practice to do it this way and all of
this is not to say that there's no
instance in which you would want to just
provide a bear value for your setter
that certainly does happen still but in
the spirit of teaching you best
practices in react it's probably good
enough just to understand what i'm
talking about here in this note and to
move on a good practice at this time
might be to delete everything that we're
doing dealing with state here and to try
and recreate it from scratch maybe as a
way to test your own skills to see if
you are truly comprehending what we've
done so far when you feel like you've
got a good grasp on this let's keep
moving forward
let's pause now and do another quick
quiz like you've done before pause the
screencast click into the editor here
actually type down your answers to the
questions that you see here and then we
will go through the quiz together pause
now and work on the quiz
okay number one you have two options for
what you can pass into a state setter
function like set count what are those
options well option a is to pass in
simply the new value of state
so if you call set count and you provide
a new value like 42 whenever this
function gets called state will
automatically be updated to the number
42 and option b is to pass a callback
function
and then whatever the callback function
returns we'll say whatever the callback
function returns will be
the new value of state
and then numbers two and three both
refer back to the answer to number one
so when would you want to use the first
option in our case the new value of
state this is any time you want to
update your state and you do not care
what the previous value of state was or
rather you don't need the previous value
of state to help you determine what the
new value of state should be
and then the answer to number three is
basically the opposite of number two
it's whenever you do need the previous
value of state to help you determine the
new value of state
under the hood react is doing some
relatively complex things to make sure
that it can maintain state for you one
of those things has to do with batching
a bunch of different state changes
together so if you were to run two state
setter functions back to back the way
that react handles it may or may not run
one of them before the other that's a
very high level overview of why we need
to do this but when we pass a callback
function to our state setter function we
can be guaranteed that the value that
callback function receives which in the
previous lesson we were calling
pre-count we can be guaranteed that it
will receive the most updated correct
version of that so that it can update
state correctly if that didn't make any
sense that's completely okay that's
really why i didn't want to dive too
deep into it because at this point it
truly is enough to know that if you need
the old value of state to help you
determine the new value of state you
should pass a callback function
otherwise you don't need to pass a
callback function okay i'm probably
beating a dead horse at this point when
you're ready let's keep moving forward
now that we've learned how to create and
update our state let's revisit our meme
generator
we figured out earlier how to get a
random url for a meme image however the
conundrum we ran into was that we
couldn't update our user interface with
that image because react wasn't
listening to our local variables now
that we know about state we should be
able to add an image to our meme
generator
so your challenge is to first create a
new piece of state called meme image
that will just start with an empty
string as a default and when the get
meme image function is called you'll
save the random url which we still have
access to right here in the state for
meme image
once you've done that you should be able
to add an image element below our div
here with the form that has its source
set to the new meme image state that you
created as a bonus you may want to add
some styling so that the image stays
confined within the space that we're
working with here pause the screencast
and work on adding an image to our meme
generator
right near the top here i'm going to
create name image and set
meme image
which will come back from react.use
state
the initial value is an empty string
down in my get meme image function we
can call set name image
and now think for a second do i need
access to the old state the old string
here in order to determine what my new
string should be
and the answer is no i don't care what
it used to be i'm completely replacing
it with the new url which i can get
through memes array at the index of
randomnumber.url
and that should complete these first two
tasks
lastly i'm going to use my new meme
image to
create an image element
and give it the proper source
name image
let's hit save and well it says we have
an error let's go ahead and just see
what happens i'll click get a new image
and look at that we've got an image now
obviously it's pretty large
let's see if we can just add maybe a
class name
and for now let's call it maybe meme
dash dash image
in my styles i'll add
name image and let's say it's got a max
width of a hundred percent
hit refresh
click get a new meme image and look at
that
now i don't know immediately what this
error is coming from i think for now i'm
going to ignore it and we'll see if we
can figure it out later down the road
awesome work now this is just the
beginning we have a lot left to learn
about state but don't let that be
daunting it's going to be really fun so
when you're ready let's keep pushing
forward
at this point it will be helpful for us
to practice the ternary operator whether
you've learned it before or not i've
written some very basic javascript here
we just have a variable called is going
out that is set to the boolean true and
then we are using that value to
determine what the answer should be that
we display in our h1 over on the page
obviously if is going out is true then
we'll say yes and otherwise we'll say no
if it's been a while since you've worked
with the ternary or you never really
fully grasped it i've included a link
here to the mdn docs on how to use the
ternary operator so once you feel
prepared pause the screencast and see if
you can clean up our code using a
ternary
a ternary allows us to put an if else
statement onto a single line technically
you can also manage if else if else
statements and get as nested as you want
by using nested ternaries but at that
point i really don't see a reason in
using a ternary it becomes much more
difficult to read than a simple if-else
statement so here what we're going to do
is set our answer equal to and then
we'll use a ternary to determine if we
are going out so i could say is going
out
is true and then i use a question mark
that says if this is true then i want
you to use this expression in other
words i want let answer equal to yes the
string yes otherwise this is my else
i'll say i want answer to equal no
i can get rid of all this down here
and i've been able to clean up my code
from before to a single line and if
you're not terribly familiar with
ternaries the more you see this the more
natural it's going to seem this is
actually a really easy thing for me to
read now because i've seen it so many
times so i can hit save
and everything is working here we can
see if i flip this to false
hit save then we get the answer no
i can simplify this ternary even further
because is going out is already a
boolean i don't necessarily need to
equate it equal to true so i can simply
say if
is going out in other words if this is
true or a truthy value
then set answer equal to yes otherwise
set it equal to no
and of course we get the same values
switch this to true no will change to
yes awesome okay let me tweak this
challenge just a little bit
there's one more way that you will
oftentimes see a ternary used in react
and that is when the ternary actually
exists inside of our markup if you
remember our curly braces allow us to
put javascript not just variables but
entire expressions directly inside of
our jsx so your challenge is to move the
ternary inside of the h1 in the jsx and
as a hint you will no longer need the
answer variable at all
pause the screencast and see if you can
figure out a solution to this challenge
all i need to do is take this part of my
ternary here and replace answer with it
and then i can get rid of my answer
completely now what will happen is every
time my component renders it will check
the value of is going out and it will
determine whether the string yes should
be used as the text of this h1 or if the
string no should be used as the text of
this h1 so just like we had before i can
hit save we get yes because our value is
true and if we switch it to false we get
our answer of no
awesome this sets us up perfectly to
work on the next challenge where we will
actually save this value in state and
then flip it back and forth between true
and false and that's what we'll work on
next
similar to last time we have the
question do i feel like going out
tonight i've hard coded this time the
answer yes but you will want to change
that in the challenge so your challenge
is to initialize some state for a
variable called is going out and you
will just begin it as a boolean you can
choose true or false as the default and
then make it so that clicking anywhere
in this div
will flip that boolean value from true
to false or false to true
and then instead of a hard-coded yes you
should display yes if is going out as
true otherwise it should display no this
rolls together the topics of the past
few screencasts so if you need to look
back and remind yourself how everything
works that's completely okay pause the
screencast and work on this challenge
to initialize some state i will simply
use react.use
state
as a reminder you could also decide to
pull in use state as a separate method
from the react library by destructuring
it up here
i'll set the initial value to true and i
will save it in a variable that i will
use destructuring on because i receive
an array back and we'll use is going out
and i will by convention use set
is going out
as my function name next i need to make
it so that this div when it's clicked
will flip that value there's a few
different ways i could do this in fact i
think i'll show you them i'll set an on
click here and one way that you may see
from time to time is somebody providing
an arrow function directly inside of
your on click one benefit of this is
that you can just declare it right here
and it is nice and concise short and
sweet in fact i'll start going down this
path and then i'll probably change to
move this function into its own defined
function outside of my return but let's
go down this road for a second when a
click on this div happens i want to run
this whole function and the main thing i
want this to do is to use
set is going out and now i need to think
do i need the old value of state to
determine the new value and yes in this
case i do i need to know
if it used to be true then i want it to
be false if it used to be false i want
it to be true now think to yourself when
i need to use the old state what do i
need to provide as my parameter to my
setter function here
if you said i need to provide another
callback function then you were right
and that's because this callback
function will give me the previous
version of state that will help me
determine the new version of state
and now that i've typed that out i can
see that this is already a little bit
crazy i have an arrow function calling
this function which takes a function as
a parameter and it becomes one too many
levels of inception for me so i'm going
to move this to a function out here
let's call it change mind
and it's going to run set is going out
and then i can replace this all with
just change mind which looks a lot more
concise and to me at least is a little
simpler to read
with set is going out i'll take my
previous version of state you can call
this whatever you want
and we will return the opposite of
whatever previous state used to be now
this is a little shorthand trick that
i've learned over the years if you did
something more like
an if statement that says if grieve
state was true then set it to false and
if it was false then set it to true
that's completely okay this is another
instance where a ternary might be useful
we could say
if
state is true then return false but
otherwise return true but all of that is
a little bit unnecessary because i can
simply say just return the opposite of
what it currently is
now last but not least i need to change
what is actually displaying on my page
now if you struggled to get to this
point first of all i'd recommend going
back and reviewing what we've learned
keep practicing until this first portion
of what we just did makes sense but
before you do that i'd also like to
encourage you to pause the screencast
and see if you can apply what we learned
about ternaries and what our current
value of is going out is to determine
what we should replace our yes with here
so if you weren't able to complete this
far then pause the screencast and try to
figure out what we should put here in
our h1
well we can just put a ternary directly
in line by putting a set of curly braces
to
tell us that we're going into javascript
and i can use a ternary that says is
going out is true then i want you to
display yes
but otherwise i want you to display no
and at this point we should have
everything completed let's open this app
we'll refresh it and when i click it
changes us from yes to no
one thing i like about using a boolean
for our state here is that it's a lot
more realistic to a real scenario i
could have possibly made things a little
bit simpler by just having this be the
string yes or no i would obviously need
to change this down here and say if
previous state was yes then change it to
no and if it was no then change it to
yes but personally i like the separation
especially if i'm going to use variable
names that start with is or has that
indicate a boolean to just use a boolean
like true or false and then translate
that true or false boolean value into
something that makes a lot more sense
for a user to actually see on the page
again if any part of this was
overwhelming or too confusing or you
weren't able to do this from memory then
i highly recommend going back reviewing
this trying to do this challenge again
don't just push forward but all in all
you are doing a great job whether you
understood this or not you've gotten
very far also don't forget to take
breaks stand up if you need to go get a
drink of water and when you feel
refreshed and ready let's keep moving on
hey this looks familiar this is the
little app that we used when we were
learning about how saving local
variables does not update our ui and now
that we've learned about state to start
us off your challenge is to convert the
code below to use an array that's held
in state instead of what we currently
have with our local variable here you
can just initialize the state as an
array with these same two items
and if i were you i would call the piece
of state that you create things array
just like we had before so we don't have
to change anything else in our code here
pause now and work on this challenge
let's go ahead and create in fact i'm
just going to reuse what i have here i'm
going to put this into an array and
have a setter function that says set
things array
and that will equal
react.use state
which i will initialize with this array
and well let's hit refresh i think this
should work just fine okay well this is
showing up at least that tells me that
things array still contains my two items
the last piece we need to fix is making
it so that our add item button will add
something to our things array however
the reason that i'm making this video is
because there is a small gotcha in here
and that is that it's tempting to want
to do something like things array dot
push
however i want you to think for a second
what is wrong with saying things
array.push
if you remember back we should never
ever directly modify our state in this
case our state is things array and here
i'm directly modifying it dot push is a
destructive action it modifies the
original array and therefore we would be
changing things array ourselves and this
just isn't a good idea in fact not only
is it not a good idea but if i try to do
it let me put a test in here hit save
and add item you can see that nothing is
going to happen here okay so we know we
need to use set things array in order to
modify our state which will actually
update the user interface on our screen
so let's use set things array and if you
remember back with settings array or
whatever setter function i have i can
provide one of two options here pause
and think for a second what are the two
different options that i could put into
the settings array
well i can either provide it with and
i'm going to put these inside of angle
brackets to show you this is not real
syntax i could either put in a bare new
value completely replacing the old value
of state with this new value or i can
provide it with a callback function and
that callback function would receive as
its parameter the old version of state
which i can use to determine the new
version of state so now i want you to
pause for a second and think which of
these options should i use should i use
the new value option
or should i use the callback function
option
well if i just provided a new value then
i wouldn't really be able to add
anything to my existing array i would be
simply replacing my existing array
because what i want to do is add an item
to the array that means that i do depend
on what the old version of state or the
old array is in order to determine my
new array
so i need to provide a callback function
here i'll do this as an arrow function
and
i can put in my
let's say prev things array
or i could simply say preview state if i
wanted to i'll keep it as things array
so it's contextual and now that i have
gotten this this far i want you to pause
and see if you can figure out what i
need to add or what i need to return in
this callback function to correctly
update my array with the new thing that
i want to add and if you remember every
time we click add item we want to
determine the length of the array and
just add thing
space and then the new length of the
array so it should automatically put
thing three when i click add item
this one can be a little bit tricky if
you spend more than maybe five minutes
or so without figuring it out you can
just hit play again and i'm gonna show
us how to do this but i do want you to
pause and see if you can figure this one
out
another really tempting thing to do at
this point is to say
grieve things array dot push
however again this is not correct
this pre things array is still a
reference to my existing state and using
dot push on it is not a good idea
because that would be modifying state
directly not only that but dot push
actually doesn't return the array that
is modified it returns the new length of
the array so this would be like
replacing all of our state with a number
which would just be three so i guess in
two ways this really isn't going to work
for us
remember i need to return a new version
of state and my state starts out as an
array in fact my program expects things
array to be an array because i'm using
dot map on it so i need to make sure
that when i'm setting a new array that i
return
a new array this is a new version of
state
fortunately with es6 there's a really
easy way for me to spread in my existing
array which i have access to with
pre-things array which by itself would
get me an array of everything that used
to be in there so this is not yet
updating it however i can very simply
add a new item to the end of my array
these are strings but i'm going to be
using some javascript to determine the
array length so i'll use some template
strings here and i'll say thing space
and then interpret some javascript by
saying
preview things array
dot length and because that's the
previous array and it's not zero indexed
and i want this to say three i'm going
to add one to it in other words my
previous array was two items long and i
want it to say thing space three so i'm
adding a one at the end this is getting
a little long so i'm going to put this
on to the next line which means i then
have to use a return
and well let's just see if this works
i'll hit save
add item awesome look at that we've got
things adding to our list with the
correct numbers and everything if you're
feeling hazy or forgetting the array
spread operator and how this works
that's totally okay although i would
recommend that you go study up on the
array spread operator because it's so
useful you're going to find yourself
using it all the time especially in
react however this isn't the only way to
do this there certainly are other ways
to make a copy of our original array or
to return a new array we could even use
a for loop that loops over this array
and pushes those items to a brand new
array then we add our string here at the
very end before we return that whole new
thing obviously this is why i'm saying
you should just go focus on learning the
array spread operator because it's
extremely useful okay i do have one big
challenge for you
okay it's time to put all the knowledge
that you've learned lately together into
this challenge in fact if you want an
extra challenge you can delete this line
where we set up things elements where
we're mapping i figured because it's
been a minute since we've looked at this
i wouldn't necessarily make you do this
but if you really want to challenge
yourself you can delete line 13 here and
try to do everything completely from
scratch like i said i'll leave this here
just in case that's a little too much to
bite off at this time so see if you can
build this all again from scratch let me
refresh this so we start from a new spot
of course this is broken because some of
the values are missing pause the
screencast and see if you can bring this
back to a working state
okay let's do this i'll use
things array and set things array
as the values i get back from
react.ustate
i'll initialize my values with thing one
and thing two and i need to spell things
right then we will use set things array
using the previous array i could say
previous things array or previous array
maybe this time i'll be a little more
generic and just say grieve state and
this will return a new array that has
all the items from preview state as well
as a new item
which says thing space
and then the number of brief
state.length plus one of course if i
leave this on the same line i don't need
to open curly braces and use the return
keyword just in case this is bleeding a
little bit long for anybody i am going
to put it back that way and hopefully
this didn't drive too many of you crazy
you can see i refresh and everything
comes back i also had taken this on
click out
sorry if that threw anybody for a loop
i'm going to add it back in and say when
the button is clicked i want you to run
add item which will run the set things
array function and do all the stuff that
we just typed in there i'll hit save
awesome we're working again i really
hope that you attempted that challenge i
know that might have been difficult but
truthfully that's where the learning
happens you won't be able to truly
internalize these things that we're
learning unless you put your hands on
the keyboard and really challenge
yourself in fact i would say that as you
come to challenges in this course and
really any course on scrimba if you
don't immediately know the answer don't
just hit play go to google ask the
community go back to previous lessons in
that course do whatever you can to try
and figure it out on your own and then
of course if you are completely stuck
you can always hit play in the next cast
we're going to see something similar but
working with objects in state instead of
arrays in state
now let's see what it looks like to use
an object in state here we have a simple
contact card it's got a first name last
name phone email and a property called
is favorite to kick us off i want you to
see if you can figure out how you might
fill in some of these values below
instead of using the hard-coded values
using the properties from state of
course they will look exactly the same
because i just copied and pasted these
values from the state up above but you
can always test it by changing one of
these values in state and seeing if it
reflects on your card there pause the
screencast and work on this challenge
let's start with the name we have the
first name and last name together inside
the same h2 but they're separated in the
state up here
the simplest way to do that is simply to
put the first name in its own set of
curly braces put a space and then the
last name in its own set of curly braces
now because my state is an object
i need to reference the entire contact
and then use the dot syntax to access
its properties
so i will say contact dot first name
and then the space which will be
interpreted as an actual space in the
markup followed by contact.lastname
hit save nothing looks like it changes
that's good if i change this to jane
our contact changes great
and then i can simply do the same thing
for these other properties this is
contact.phone and contact that email
now i mentioned that we're going to
ignore the is favorite property for now
i have another challenge that i'm going
to type out now
you might notice in the images that we
have two separate pngs one called star
empty png and one called star filled png
right now we're just using the star
empty png but if this were filled
and let me comment this out so it
doesn't break our code you'll see that
it fills in the star nicely as if this
contact were a favorite of yours however
following the declarative nature of
react we want the is favorite property
to be the determining factor as to which
of those two images gets used so your
challenge is to use a ternary right here
in this line i'll uncomment this now to
look at the contact.is favorite property
and determine which of the following
file names should be used based on the
value of the is favorite property then
you'll want to use that star icon value
which will just be a string here to
figure out what the source should be for
the star image in fact i'll add that to
our challenge
okay best of luck pause the screencast
work on this part of the challenge
on line 21 i'll replace this comment and
we'll simply look at contact dot is
favorite i technically could equate this
to true or false but because it's
already a boolean i just need to say
contact that is favorite if so
i want to use the star filled png
and otherwise i want to use the star
empty png
and now that i have a value for star
icon i can simply replace whatever is
here
with
star icon you'll notice i had put
backticks here to begin with just to
make things a little easier that's
because i knew you were going to be
putting in an interpolated value like
that i'll go ahead and hit save
everything looks the same but now if i
change my is favorite from false to true
in the hard-coded initial value
we get a little filled star now that
we've learned how to apply state that's
in the form of an object to our actual
markup in the next screencast let's
learn about how we can update state when
state is an object
our goal is to be able to click the star
icon and have it flip our is favorite
value from true to false or false to
true however currently our is favorite
property is nested inside of this object
when i call set contact i need to
provide a new version of state to
replace the old version however in our
case i don't want to replace any of this
other information i only want to change
the is favorite value many people's
first thought is to use set contact and
here you'll see i already have set up a
toggle favorite function which is called
anytime the little star icon image is
clicked
right now it's just console logging
toggle favorite a temptation is to use
set contact look at the previous contact
information
and return and i guess for simplicity
i'll put this on its own line we'll say
return an object where the is favorite
property is the opposite
of the previous contacts is favorite
property however there is a major
problem with doing it this way i'm not
going to hit refresh yet but i do want
you to pause the screencast and see if
you can figure out what mistake i have
right here
remember that in this callback function
whatever i return
from that function will become the new
replacement for our contact state
currently i have an object with five
properties first name last name phone
email and is favorite but what i'm
replacing it with is an object that only
has one property is favorite so if i hit
save
and then click our toggle favorite
you'll see that all of our other
information just disappears however it
does look like our star is working i can
click our star and it is correctly
flipping back and forth but obviously
this is a bug if you do happen to be
coming to this course having had
experience in class base react this
might seem confusing to you if you've
never worked with class base react you
can ignore the next thing i'm about to
say but in class base react when you use
this dot set state it would
automatically figure out how to combine
your old object with the new property
that you're trying to replace it with
however using hooks with react.ustate
no longer does this okay everybody can
tune back in now the main point is that
i need to make sure that i bring in all
of the properties of my old object and
then replace the one or two or however
many properties you need to replace in
what you're trying to accomplish a very
simple way for me to do that is to
spread in all of the properties of my
old contact and in this case i have
access to the old contact using preve
contact so i'll bring in all of the
properties and this by the way does
include the is favorite property but
then i will overwrite the is favorite
property with a new value in effect it's
like taking this whole thing copying it
pasting it in
just like this where we have our old
first name old last name old phone old
email the old is favorite and then we're
saying actually i want a different is
favorite believe it or not this is not a
syntax error instead it just takes the
second one that's declared or rather the
last one that's declared and uses that
as the actual value for our new object
this is much more verbose than it needs
to be so i will use my spread operator
instead like i had before
i'll hit save
notice this is filled in because my
value is true by default i should
probably set that to false by default
and then when i click it all of the
other information stays the same except
for the value of is favorite which is
then redetermining which icon is going
to be used based on that contact is
favorite property
i totally understand that this can be
complex this was one of the more
difficult things that i had to grasp
when i was first learning how to do
state and react so to see if you were
paying attention this is your time to
shine
your challenge is to simply rebuild what
we just had again if you get stuck and
you don't remember the syntax don't just
hit play and watch me do it open a new
tab do a quick query on google see if
you can find a resource that will help
you figure this out or even go back
earlier in the screencast and see how i
did it so that you can then come back to
this point and type it out yourself so
pause the screencast and see if you can
rebuild our toggle favorite function
okay let's do it we're calling set
contact
we do care about the previous value of
our state in order to help us determine
the new one not only because we need to
know what the value of is favorite was
but also because we want to make sure we
maintain all of the other properties
so in that case i'll use my callback
function
i'll let it pass preve contact to it and
i will use that to
return
a new object and here's actually a quick
aside it might be tempting to say well i
just want to use the implicit return and
say take this function return an object
however these curly braces are being
interpreted as the opening part of the
function body if i do want to literally
return an object i need to surround my
object with another set of parentheses
this looks a little bit crazy maybe just
to show you that it works i will leave
it here and for brevity i suppose so
given our previous contact i want to
return an object that has all of the
values of our previous contact
but changes the is favorite value to the
opposite of whatever it currently is
i'll hit save
it's empty by default because is
favorite is false
and i can toggle that on and off
i hope that challenge went well if you
felt like it was a struggle then of
course as always you can go back and try
it again as i've always said the easiest
way to learn something new is to do it
the hard way and i imagine some of you
out there when you saw me delete all of
the code inside of here maybe had a
little panic moment and he thought oh no
he's going to make me do this by myself
but your growth in understanding of
react will only happen as you type this
stuff out yourself watching me do it
alone is not going to help you learn it
so as always once you feel comfortable
enough that you could write this out
again all by yourself that means that
we're ready to move forward
when we last left the meme generator we
were getting a weird unknown error being
thrown from react i looked into it and i
realized that it was because we were
initializing state as an empty string
and react was not taking too kindly to
having our image source set as an empty
string so i just went and grabbed a
placeholder image for now and that seems
to have gotten rid of the error
just thought i'd give you a quick update
on that error our challenge in this
screencast is to update our state so
that we can be well prepared as we learn
more to save that state and ultimately
finish our meme generator so your
challenge is to create an object in
state we'll call it meme and it should
have a property for the top text bottom
text and the random image that we choose
you can default the top text and bottom
text as empty strings and i would
default the random image to the string
that i have below so that we don't get
that same error we had before
next i want you to create a separate
state variable called all meme images
this all meme images variable is going
to hold an array of all of our memes
data which for now you can default to
the memes data array that we imported up
here
then lastly you'll want to update the
rest of our code to use these new state
variables so that in the end we have a
working app the way that it's currently
working
so pause the screencast and work on this
challenge
let's comment out our old state here
just so we don't get confused and we'll
create some new state with meme and set
meme
equal to react.use state
and this one's going to be an object so
i'll put my curly braces and we'll put
in our three properties we have top text
which is an empty string
bottom text also an empty string
and random image which will be
the same as what we had before in our
old meme image state variable
then we need another state variable so
we'll create a new one we'll say this is
all meme images and we can say set all
meme images as our function here
react.use state
and the initial value is going to be our
memes data array that we imported above
with those set up we really just need to
update the rest of our code
so anywhere i was directly accessing
memes data i'm now going to
use all meme images
and then we have a bit of a gotcha here
before when we were just saving the meme
image as a string we were able to just
completely overwrite whatever the old
string was and replace it with the new
url however now the random image which
represents our new version of meme image
is nested inside of an object so first
of all we need to use set meme instead
of set meme image
and instead of what we had before we do
need to look at what the previous meme
was in order to determine the new one
because we have properties like top text
and bottom text that we don't want to
lose i think i'm going to save this as
its own variable so i'll say url equals
the memes array at the index of
randomnumber.url just to make my life a
little bit easier and now i'm going to
access the previous meme and return an
object i'll surround it in parentheses
so i can use my implicit return we'll
pull in all of the properties of the
previous meme and then we will alter the
random image property
to
be our url let's scroll down and see
down here we have on click get meme
image that's still going to be the same
because that's our self-defined function
however here instead of meme image
we want to say meme dot random image
and let's cross our fingers we'll hit
refresh
i can click get a new meme image and
awesome we're working just the way we
were before obviously our top text and
our bottom text is not yet doing
anything but we're first going to have
to learn about forms and inputs and how
to save state which will be happening
later down the road
all right awesome work let's keep moving
forward
at this point we've learned to use a
number of really cool tools and react
like state and props now we get to start
using those tools in creative ways and
putting them together
your challenge here is honestly pretty
contrived i can't think of a reason why
you would actually want to do this but
for the sake of practice i want you to
create a new component named count which
will essentially replace these three
lines of code in other words you'll
create a new component name count it
will render this div with this h1 and in
an effort to practice props we're going
to pass that new count component a prop
that we'll just generically call number
the value of that prop number should be
the value of our current count i promise
this isn't just busy work we are
building toward a point pause the
screencast and work on this challenge
okay i'm gonna do this working backwards
so my div here i'm going to cut this but
keep it in my clipboard so i can paste
it later and i'll render a component
called count which i obviously haven't
yet created
we said we're going to pass to it a
number prop
and i'm going to set that equal to the
current value of my count up there
now i need to import it if i'm going to
use it here obviously it still doesn't
exist but we'll just pretend it does so
i'm going to import count
from a file called count
and then i need to create that file and
work over there so i'm going to create
count.js
import react from
react
and i'll just spin up my basic component
here
called count and i need to make sure
that this is receiving props because i'm
going to use that number prop
i'll have it return and i'm just going
to paste that div that i had before
okay and now it doesn't have a count
variable anywhere in here remember
before this was referencing the state
value of count
but now i'm receiving it through prop so
i can say props dot and it's not
props.count because the prop we passed
to it was called number props that
number
i'll hit refresh and you can see
everything is working exactly the way it
was before now as i mentioned this is
pretty contrived i can't imagine why you
would care to put a count component in
its own component that just displays a
number especially when it's only three
lines of code unless for some reason you
are going to be reusing this component
in different contexts around your
application
let me clean up this challenge and then
we'll talk about why i had you do this
as i've mentioned we've learned how to
use props for a component to be able to
receive values like we've done here
and we've learned state and how to have
a component declare its own values that
are intended to change and update the
user interface when those changes happen
and now all we're doing is we're
combining those two concepts we are
still initiating state inside of our app
component but then we're passing that
state value down to a separate component
called count and it's receiving that
value as props
now we're going to see something cool
that react does
let me inside of my app component
console log
app component
rendered
anytime react creates an instance of our
app component which is happening here in
index.js
it will run this function and part of
that function will console.log app
component rendered then we'll go ahead
and do the exact same thing in the count
component
and we'll change this to
count component rendered
now before i hit refresh as a reminder
the word rendered simply means that it
placed the elements that react knew it
needed to place on the screen so when i
say app component rendered it means that
it took the markup of our app component
and it painted it to the screen or it
placed it on the screen it created the
dom elements and the styles that it
needed for it to display correctly on
the screen and you can see there's a
sort of cascading effect here
over in index.js we render an app
component
when we go to app we see that it renders
a count component and it's doing that
down the line so it will first say app
component rendered i'll open the console
and hit refresh
we see app component rendered and count
component rendered now there's a really
cool thing that react does for us and
that is whenever state changes it will
re-render the component where the state
exists and any child components that may
rely on state to be working correctly
and if you think about it that makes
sense if i'm going to change my state
from 0 to 1 i'm going to need my
component here to re-render which will
then cause this count component to
re-render and it will pass the new value
of count and that way it can very
quickly and seamlessly update what i see
on the page just by re-rendering those
components
we're not going to dive deep at this
point into understanding exactly how
react is re-rendering which components
it's re-rendering and optimizing which
components it's re-rendering that's a
topic for a more advanced course but for
now it's a good experiment to have these
console logs here and see that every
single time we change our state it's
re-rendering the component in which the
state is declared and any children
components like our count component here
that may or may not depend on the state
value for count
awesome now we've seen an example of a
child component receiving a state value
via props now we'll look at how a child
component might be given access to make
changes to its parents state
okay here we are back at our little
contact card with the favorite icon your
challenge to start us off is to move the
little star image just this one little
image element into its own component and
maybe we'll just call it star that'll be
the name of the component
and it should receive a prop called is
filled that the star component will use
to determine whether the icon should
display
the filled png or the empty png
then inside of this component here
you'll need to import and render the new
star component
and make sure to pass the correct value
of is favorite our contact dot is
favorite to that is filled prop
at this point it's not going to work the
way it was before where we could click
it and flip it on and off for now in
order to test it you can simply change
this value from false to true and it
should if it's working correctly display
the filled in star when you change that
to true
there's a few different moving pieces
here so this is a slightly more
difficult challenge than the ones we've
done up until now but i know you'll be
able to do it pause the screencast now
and start working on this challenge
once again i think i'll work backwards
i'm going to
cut this image out
and i will render a star component which
i have not yet created i'll give it this
is filled prop
and it will be the value of contact dot
is favorite let's import this and then
we'll go and create it so i'll import
star from
dot slash star
and then i'll create that file star.js
okay and in this case i need to make
sure that i'm receiving props because i
will need them i'm going to return and
then this image element
i'm going to get to this on click in
just a second but for now let's figure
out our star icon i'm going to just set
star icon equal to and then actually i'm
just going to go take
exactly what i had here and then make a
slight change
okay now we don't have access to our
contact state because we're not passing
it down however we do have a replacement
is filled
and that's part of props so it's props
that is filled
and then this will determine which
image should be used let me remove my on
click so i don't get an error we'll hit
refresh and see if we missed anything
okay awesome now my star is empty and
that's because this value is false let's
test this by changing it to true
and the stars failed awesome and at this
point i can remove this line because i'm
not needing that anymore and at this
point that leads us to the topic of this
screencast and that is how do i make it
so that i can change this value clicking
it is not doing anything
the conundrum that we have is that we
have a child component that's receiving
the value of his favorite through props
but it is not receiving the ability to
change that state so think for a second
how can i give my child component the
ability to make changes to the state
that lives inside the parent component
which is app
in fact i want you to pause and try to
think through a solution to this you
don't actually have to type it and try
it out but just try to think how could i
give my child component the ability to
make changes to the state that lives in
the parent
one thing that can be tricky when you're
first learning react is the thought that
you can just add a click event listener
on your star component so what if i just
said on click equals toggle favorite let
me hit refresh and click this and you'll
see well it's not quite working why do
you think that this isn't enough for
this to work
remember when we have a component that
we created a custom component that we
created all of the properties that we
pass it are custom properties so simply
putting on click here doesn't magically
register it as an event listener the on
click attribute needs to exist on native
dom elements like these ones that begin
with lowercase letters that's because
these are what will actually get created
into real dom elements by react however
star with a capital s is not a real dom
element instead what's happening is
react is looking at the star component
and it's rendering this image
this image has the ability to receive
an on click event listener so what i
could do is still pass on click here but
realize that on click is just a custom
prop that happens to be called the same
name as the event listener in fact
oftentimes this will be changed to
handle click just to make it very
obvious that it's not a native event
listener and then over in our star
component i can add a real on click
event listener and say the value of this
on click will be the function that comes
from props dot handle click in this case
my app component is passing this toggle
favorite function to a child component
and allowing that child component to run
it whenever a certain event like the
click event happens however it's
important to note that the context in
which the toggle favorite function
exists is still here in the parent which
means that it can change the state that
lives inside the parent let's hit
refresh we'll click our star and we see
that we're back to working the way we
thought
so as a recap we created our toggle
favorite function
we passed it to our custom component in
a custom prop called handleclick and
then over in the star component it's
receiving props and it's registering a
real event listener on click whose
functional value is the function that we
received through props dot handle click
the ability to pass state setter
functions like this one down to children
components is especially crucial in
react and that's due to the fact that
the way that reacts hierarchy is set up
when it passes data and this is what
we're going to talk about in the next
lesson
at this point i think it's worth taking
a high level look at how data is passed
from one component to another in react
let's imagine we have a fairly simple
app which has the following components
just represented by rectangles for now
in this tree this top component
represents a top level component for
example our app component in a system
set up like this
and the lines indicate that this top
component is rendering these other
components
in some cases that component may just
render regular dom elements like divs
and h1s or it may render additional
custom components like we see in this
box where it's rendering two other
components i didn't put any names on
here because that's not that terribly
important the point is that there is a
parent child relationship between these
components let's imagine on one of these
bottom level components we initialize
some state
and then we find that a sibling
component in other words a component
that is also rendered by the same parent
is in need of some of the data that
lives in the other components state well
what exactly can we do then think for a
second is there a way for us to pass
that state to a sibling component
it turns out that no this is not
possible and that's because if you look
in the file of a component that has a
sibling component it has no reference or
knowledge about a sibling component on
its own if we look in our code here we
have an app component that is rendering
a header component and a body component
but if we were to go into let's say the
header component we see that i've
initialized some state here i can open
up this preview so you see what we're
working with
and it's using that state but then if a
sibling component like the body needs
access to that state well the header has
no idea that body even exists only its
immediate parent app is the component
that knows that both of these components
exist
so think for a second what is it that we
need to do if we're facing a situation
like this
well what if we took our state in this
child component and we raised it up into
the parent component now that it's up in
the parent component do we have a way in
react to pass data from this parent
component to the child components
yes we do that happens through props
so now the parent component is in charge
of the state it passes the necessary
state down to the child components that
require it and they can simply consume
the state
if that state were ever to change react
will update this component where the
state changed and it will also update
any children components as well and so
therefore if that state changes that's
being passed through props the child
component can update as well
as your application gets more and more
complex you will find yourself having
another component that sometimes needs
access to that state as well and just
like before there's no way for us to
pass the state or any kind of data from
one sibling component to another
component but it's also important to
note that there also is no way to pass
data upwards in react
this child component has no idea that
this other i guess you could say uncle
or ant component exists and therefore
there's no way to pass data that way
either so this brings us back to the
same solution we had before we simply
raise state up a level and we pass more
props downward now over time this can
get pretty tedious especially if your
state ends up raising up multiple levels
above the component that needs it in
which case react does offer a solution
to this called context there's also
third-party state management systems
like redux that can help solve this
problem however both of those are beyond
the scope of this course and we are just
going to be sticking with regular state
and props for now so that leads me to a
challenge i want you to take the state
that currently exists only within the
header and raise it up a level
into the app component and then pass it
back down through props to both the
header and the body then in the body now
that it's receiving the state from above
replace this underline with the state
which is the name of the user
pause the screencast now and work on
this challenge
to raise the state up we'll simply take
this line where we're initializing our
state
and we'll move it into our app component
and then i will pass those props down in
this case it's a very simple state of
just the string joe so we will create a
prop
maybe let's just call it user
and we'll set that equal to our user
state variable here
then in both the body and the header
we'll need to accept props
and we'll display props dot user
and in the header
props
props dot user
clean up this challenge
hit refresh
and there we go now if i go to my app
and i initialize my state differently
say bob
and good it updates in both places
understanding that this is the way data
flows in react can be really crucial in
helping you architect your application
in a way that you can share state
amongst only the components that need it
and in fact that's an important
distinction to make at this point it
wouldn't be a great idea to initialize
state way up near the top of your
component if you don't have components
along the entire tree that need it now
i'm not saying that every component
needs to have access to that state for
it to work but if this component down
here is the only one that needs state
there's no reason for me to put state in
its parent or its grandparent and then
pass stuff down through props as a rule
of thumb keep state as local as you can
or in other words keep it as closely
tied to the component or components that
need it as you possibly can with this
under our belts i think it's about time
for us to jump in and do a round of
challenges to really exercise what
you've learned up until this point and
we will start that in the next
screencast
this is the beginning of a series of
small challenges to really reinforce
some of the past topics that we've been
learning about the first thing i want
you to do is to take a look at boxes.js
you'll see i created an array of objects
which have two properties id and on
and your first challenge is to
initialize some state inside of our app
component with the default value being
this boxes array and then i want you to
map over that state array and display
each one as just an empty square on the
screen with a black border and a
transparent background color i don't
think you necessarily have to set it as
transparent i think it'll just be
transparent by default for now don't
worry about using the on property at all
although you probably will want to use
the id property and i'll let you figure
out why
if you're using something like a div
don't forget to set a height and a width
in the style on it ultimately the goal
is to make it so that if the box is set
to on or on as true then the box will be
filled in with a color and in the end
we'll make it so that clicking the box
will flip its on value from true to
false or false to true
but for now let's just get some boxes
displaying on the page pause the
screencast and work on this first part
of the challenge
we'll start by initializing some state
so i'll say
i don't know maybe for now we'll just
call them squares and by convention
we'll say set squares
that's going to be from react.usestate
and we'll pull in the boxes as the
initial value
then we need to map over the boxes i'll
save my array of elements i'll maybe
call it square elements
and that's going to be squares.map for
each square that we're looking at i want
to return a div
and notice here that i'm using
parentheses instead of curly braces
that's simply allowing me to use the
implicit return to return the element
and i'm just moving it onto its own line
so it doesn't go too far to the left and
right
we'll give this div a class name
let's call it box
and actually this is a class name so it
can just be the string box i also know
because i'm mapping that i'm going to
run into that issue where i need to
provide a key
in this case i can use the id property
that's coming from each of these objects
let's display our square elements and
then we'll go into the style so that it
will actually show up or rather i should
say let's render our square elements i
don't think they are going to look like
anything on the screen yet it's just
empty over in our style we'll set a
style for box
and we'll give it a height maybe we'll
do 100 pixels and a width of 100 pixels
we'll give it a border
that's black and then maybe just so we
can see everything i'll put these into a
really simple grid just so that i can
put them side by side a little better
actually i might not even bother with
that let me give these a display of
inline block
and i'll just put a little bit of margin
right on them
honestly this is going to be good enough
for right now
and awesome okay
the main things that i wanted you to
take away were to practice setting state
or initializing some state and also
practicing the dot map method to create
an array of elements that we can display
on the page
as well as reminding you about this key
property if i take this out i'm going to
get that warning that react always gives
if you use a dot map to create elements
but forget to add a key prop
so i will put that back in awesome work
on the next cast let's do the next part
of this challenge
before we can do the next challenge we
need to learn about the style prop you
might be familiar with the concept that
in html i can add an attribute called
style and in here i can insert css code
for example i could give my div with the
id of root or actually you know what
let's do this on the body i could add a
style and say the background
color is black
hit refresh and sure enough my entire
background color becomes black just like
i can do this in html i can do the exact
same thing in react
however because it's react and it's
javascript i can change the style
dynamically depending on for example the
value of our state or the value of
incoming props on a component let me
refresh this so we get our boxes back
and actually i think i might just add a
tiny bit of border radius to those boxes
okay to add dynamic style i can add a
style prop to my div and in react i'm
not going to put a string the same way
we did in html
instead i'm going to provide an object
now here's something that really
confused me the first few times i saw it
this set of curly braces does not
represent an object it simply represents
me entering into javascript
outside of jsx or rather it allows me to
put javascript inside of my jsx as we've
learned before since i need to represent
my style as an object i'm going to put a
second set of curly braces this inner
set of curly braces represents an object
a javascript object and this first set
of curly braces or the outside set of
curly braces represents me going into
javascript from jsx
oftentimes to avoid any confusion what
i'll do is i will not define that object
directly inside of my markup but instead
i will create a separate variable maybe
called styles and set that equal to an
object this makes it a lot more clear
and i can just put styles directly
inside of my markup here one thing to
know about these styles is that they
need to be camel cased so if i'm
changing the background color i can't
say background dash color because this
is not a valid key name in a javascript
object not only that but when i'm
modifying the properties of a dom
element you might remember that i could
do something like document.getelement
we'll say some kind of id
and i can say dot style
dot
background color with a camelcase
property name and set that equal to
something essentially that's exactly
what we're doing here we are setting the
style attribute of our dom element to be
an object hence i can use the dot syntax
here
and then i'm using the background color
css property but of course in the camel
version for javascript then because this
is an object i'm not going to use the
equal sign i'm going to use the colon to
give my key a value and i don't know
let's set it to black for now let me get
rid of this equals so that actually let
me get rid of that whole line since i
don't want to be doing manual dom
javascript here oh cool look i refreshed
my styles which include a background
color of black are now being applied as
the style of every square that i'm
rendering or every div that i'm
rendering
so why is this beneficial over just
using css well because i'm using
javascript i don't necessarily have to
have a hard-coded black value here let's
suppose for a second that my app
component is going to receive a prop
that's called dark mode
in fact let's go over to index.js and we
will say that the app component is
receiving a prop called dark mode and
let's set it to true for now over in my
app i'm accepting props here and i will
have a prop called props.dark mode and
let's say that if my props dark mode is
true i want it to be black and if it's
false i want it to be i don't know
something light well this is something i
can use a ternary for and maybe i should
be more specific this is something that
you can use a ternary for
using your knowledge of ternaries make
it so that if props.dark mode is true it
will set the background color to this
hex value here
and if it's false it will set it to this
hex value here
one important thing to note is that
these values need to be strings because
we're in javascript we're not in css
pause now and work on this challenge
let's take props.dark mode
and we will put it here and i'll say if
that's true then i'm going to use this
string
and if it's false i'm going to use this
string
and it looks like i might have deleted
my curly brace there okay awesome now we
can test this by simply changing my
dark mode value from true to false
and awesome look at that it worked great
this can be a really fun one to play
around with if you'd like you can pause
and just play around with some of the
other properties that we can change in
the styles or you could try a little
challenge of your own to see if the
number of squares in this array is even
then make them all one color or if it's
odd make them all another color really
your imagination is the limit here when
you're ready we will move on to part two
of our original challenge
it's time for part two of this challenge
i want you to move our div here into a
separate component called box and then
when you're mapping over our squares you
will render that box component that box
component should receive a prop called
on
and it will be the value of this square
dot on from our original boxes.js each
one of them has an on property and that
value is what you're going to pass to
your new box component then inside of
that box component i want you to create
a dynamic style like we did in the last
screencast to determine the background
color of the box if the box is on then
you should set the background color to
this hex value and if it's off you can
just set it to the string none pause the
screencast and work on this challenge
let me create a new file called box js
i'll set this up like normal
i know that this component will be
receiving
props and i'm just going to copy this
div
and
have that get returned
now my key is going to be broken and
actually i'm going to pass this key into
the box component so let's go ahead
and render our box component
which will be self closing
this class name is already handled on
the div that box is rendering
however i will keep the key right here
the next part says to pass it a prop
called on so i'll say on equals and then
the value will be square dot on again
each square here represents one of the
objects in my array and that has a
property called on
let's just make sure that everything is
working so far in my box component i
will console.log props dot on
and because i have six instances i
should get six
values here oh and of course i did not
import my box component so i need to
import box from box
okay let's try that again awesome okay
so i get my six values true false true
true false false and that's matching
perfectly with what i see in my data
here
then the last part of this challenge is
simply to make use of props.on to
determine what the hex value or the
background color should actually be
so using dynamic styles i will create a
variable called styles
and that's going to be an object where
the background color
is going to look at props dot on and if
it's true it will be this dark color
and if it's false it will be none
then i can simply add a style prop
notice that my variable is called styles
you really can call this whatever you
want however this attribute or this
property needs to be style exactly that
way
so i'll set that equal to the object
that i created above and i think i
should see this one is dark it was true
false true true false false so this one
should be dark this one and this one
should be dark and the rest should be
clear
and that's exactly what we get next
we're approaching probably the most
challenging part and that is where
clicking the box will actually flip the
on value from true to false or false to
true i'll give you some hand holding in
that challenge but honestly it's going
to be a pretty fun one so that's what we
will work on in the next lesson
in the next two challenges we are
actually going to be starting to dip our
toes into some intermediate react topics
here the concept of changing state is
what we have been practicing this whole
time however we're going to see two
different ways that we could structure
this project and talk about which one is
going to be the better of the two i put
together a little diagram to make this a
little simpler to understand right now
we have an app component and this app
component is keeping track of an array
of data
we're then using that array to create
box components for every item in that
array and passing to those box
components a prop called on which will
have the value either true or false
currently those box components are then
taking this incoming prop and
determining what the background color
should be however at this point in time
they have no way to modify that incoming
prop
keep in mind that in reality a component
should never modify props
in other words my box component should
never say props dot on equals something
different
however we do have some ways that we can
still make changes to the background
color of our box and that's what we're
going to be talking about the first way
we're going to see is to initialize new
state in each one of these box
components and set its initial value to
the incoming props.on value one benefit
in doing it this way is the simplicity
in allowing each box to then update its
own state of course by doing so
automatically every instance of our box
component will also have the ability to
update its own state when i first
started learning react this was the most
obvious way to allow each of these boxes
the ability to flip its own value
and so that's what your challenge is
this time i want you to create some
state inside of our box component you'll
determine its initial value based on the
props dot on value you'll also create an
event listener so that when the div of
the box gets clicked it can flip the
value from true to false or false to
true while you're at it don't forget to
update your styles here in this ternary
currently it's looking at props.on
you'll want to make sure that you're
looking at the local state instead of
the incoming value of props.on and the
last thing is a quick change i made in
the previous screencast i had set this
to none but it turns out this should
actually be transparent if i want this
to empty out the color so don't let that
be confusing okay this is your time
pause the screencast and work on this
challenge
in truth this is very similar to what we
have already done so far i'll initialize
some new state we'll call it on
and it will also receive our setter
function which i'll call set on
by calling react dot use state the
initial value should be determined by
looking at props dot on i'm going to
update this to not look at props dot on
anymore but to look at my new state
value of on and that way when i make a
function let's call it toggle
and it calls set on looking at the
previous version of on and simply giving
me the opposite of whatever that
previous version of on was
i can then
set this up as a click event listener
to run toggle
should be able to clean this challenge
up
hit refresh and sure enough i'm able to
flip the value
now it's not readily apparent but keep
in mind that what we've done is we've
given each one of these boxes its own
value of state
so basically we've given it the ability
to control itself we've given it the
control over its on value now i
understand the boxes seems a little bit
contrived however this same concept
would apply to something like a to-do
list for example our app would be like
the to-do list and each of these boxes
would be like a to-do item the value of
on might be replaced with a value called
maybe completed as to whether or not
that to do item has been completed
structuring it the way that we just did
here every item in our to-do list would
be in charge of knowing if it by itself
has already been completed or not when i
first started writing react this seemed
like the most obvious thing to do
however i've since learned that there
actually is a better way to structure
our application so that state is only
held in the app component in our example
here there certainly might be situations
where creating state in each one of the
child components and initializing that
state based on the incoming props might
make sense however general consensus is
that if you find yourself initializing
state by using the incoming value of
some prop there's probably a better way
to do this and that's what we'll be
diving into in the next lesson
previously what we did is we created new
state inside each of our box components
and initialized that state based on the
incoming prop of on and it turns out
there's actually a name for when you
create state that is initialized by
incoming props and it's called derived
state
and i'm sorry to break this to you but
it turns out that you probably don't
need derived state this is an article
that was written in 2018 you can click
on the link it's in the react
documentation it will probably get a
little bit heavy if you're still a
beginner in react but it turns out that
there can be some weirdness that happens
if you pass a prop to a component and
then just take that prop and set state
based on that prop if you think about it
in app.js we actually created some state
in app.js to maintain all of the squares
already so when we set state in each one
of our boxes we had state both in the
app and in every one of our boxes which
in the end means that there are two
sources of truth when the box had the
ability to update its own state it was
not updating the state on the app
component it was only updating its local
state that it had derived based on the
incoming props and because of that there
were multiple sources of truth now
certainly there are circumstances where
derived state makes sense this article
does talk about some examples of that
however it's far less common than i
think most people end up using when
they're writing react applications and
the whole reason i decided to talk about
this in this course is to help you
navigate a scenario that at least for me
was really tricky when i was learning so
we're going to approach this in a
different way instead of putting state
and a setter inside of each one of our
boxes we're going to make use of the
state that already exists in our app and
instead we're going to create a function
called toggle inside of our app
component and then pass that toggle
function down to each one of our box
instances anytime one of the box
components gets clicked it will run this
toggle function and essentially tell the
app component hey
the state that you're maintaining needs
to change then when that state changes
let's say this first object gets clicked
and it changes from true to false react
will re-render the app component because
its state has changed and therefore will
re-render the box components but now
with the first one having an on value of
false you certainly are going to notice
that this way of doing things is more
complex
however in the end it is a better
practice than using derived state to
manage our state
because of the additional complexity i'm
going to give you a challenge that has
you doing part of this and then we're
going to walk through completing it
together
so let's go ahead and get started
the challenge is for you to create that
toggle function that for now is just
going to log clicked to the console then
i want you to pass that function down to
each of the box components and set it up
so that when they get clicked it simply
runs the function which means it will
console.log clicked i've already removed
the state from our box component so that
isn't something you have to worry about
pause the screencast and work on this
challenge
okay let's create a function called
toggle
simply enough it's going to
console.clicked
then we're going to pass that function
to each one of our boxes we can choose
the prop name we want sometimes i'll use
what looks like the on click event
handler but keep in mind that because
this is a custom component it won't
automatically register this as an event
listener i think more often i'll choose
something like handle click that makes
it very clear that i'm talking about
handling an event however i also could
just give it the name of the function
really we can do whatever we want here
let's stick with toggle for now and
we'll pass down the toggle function and
now inside of box js i'm receiving a
prop called toggle and this is where it
does need to be on click with the
capital c
we'll use props dot toggle
i'll hit save
and clicking it awesome runs the
function that we defined this is the
point where some additional complexity
needs to be added in in order for this
to work correctly when each box was
initializing its own state it was really
simple to know which box was flipping
its value because well each box was
maintaining its own state however now
with our toggle function the toggle
function has no idea which box just ran
its code
so in my app component if i wanted to
use set squares because squares is an
array i need to figure out which of the
items in the array triggered set squares
so that i can update the correct one and
leave all the other ones exactly how
they were and this is where we are
essentially forced to do something a bit
clever and i figured at this point it'd
be better for me to walk you through
some examples of how we might solve this
problem let me clean up our challenge
our goal is to give the toggle function
the ability to know which box was
clicked so that we can correctly update
the state array
one way we could do that is to make it
so that the toggle function takes the id
of the box as a parameter however as
it's currently set up this is not going
to work and that's because in our on
click here we really don't get to decide
what parameter gets passed to our
function every browser will pass an
event handler function the event itself
it's an event object that describes a
bunch of information about the event in
fact i can see that really quick here i
will instead of console logging clicked
let's console.log id which we're going
to be disappointed in what actually
happens i'll hit save
click a box and you'll see i get a
synthetic base event clearly not the id
of the box that was clicked however we
can work around this by instead of just
blindly running props.toggle we can run
our own function which then runs
props.toggle
this is the function that is going to
receive the event however we're not
going to make use of that so i'll just
delete event and then this function can
run props.toggle and now we have the
ability to pass whatever we want here in
this case what we should pass is the id
of this box however currently we're not
receiving that id sure i have this key
prop however the key prop really is
intended for something completely
different and i'm fairly certain that if
i even tried to access that key prop
let's console log props dot key
yeah i'm going to get a bunch of
undefineds i don't have access to
props.key inside of this component but
that doesn't stop me from passing
another prop
let's call it ib
and it essentially is the exact same
thing now i do have access inside of box
to props.id so if i console.log props.id
i get the ids of each of the boxes and
now i can use props.id to pass that
information past the id to my toggle
function
now over in app.js if i console log the
id that's coming in of course this will
only run when i click it let me click
the very first box and that is my id of
1 this one should be two three four five
and six
awesome this is great news because now i
can use that id to update the correct
square in my set squares function
at this point i think this is something
that you'll be able to do as a challenge
this lesson is getting a bit long so
that's what we'll do in the next lesson
i'll admit right now this challenge is
going to be a little bit tricky your
goal is to use our set squares function
to update the correct square in the
array remember we're receiving the id
and we just want to flip its on value
from true to false or false to true
however the trick is to not change state
directly as a hint you could go back to
the lesson on how we updated a raise and
state if you need a reminder on how to
do this however in that lesson we mostly
just touched on adding new items to that
array in this case we're not adding new
items we are updating one of the
existing items at this point it might be
tempting to use an array method like
splice however that is going to directly
modify your state because splice alters
the array that it's run on
so don't let any of that scare you i
really want you to try your very best to
do this if after maybe 20 minutes you're
still struggling on figuring this out
you can always just hit play and we will
walk through this together so let's have
at it pause the screencast and work on
this challenge
okay we'll use our set squares function
as usual we do need access to our old
version of squares in order to determine
the new value of our squares so i'm
going to say previous squares and
instead of getting really clever and
figuring out a way to do this on a
single line i'm just going to open up
this function so we have some breathing
room to create variables and do whatever
we need in fact let me solve this in
maybe the least clever way i can think
of i'm going to create a new array we'll
say new squares i'll set that equal to
an empty array and i'll do a very simple
c style for loop we'll say
let i equals 0 i is less than
previous squares dot length
i plus plus
and my goal here is to look at each
square in the array of squares
and if its id is equal to the id that
our toggle function got then we will
simply flip the on value to the opposite
of whatever it currently is
if we are looking at a square that is
not the one with this id then we'll
simply push that to our new squares
array
so let's say our current
square
is the array of previous squares at the
index of i
and now i'll say if our current square
that we're looking at has an id that's
equal to the id given to our function
then i'll say
maybe updated
square
is equal to an object that has all the
properties of my current square except
the on property is going to be the
opposite
of my current square dot on
and then i have this new object and i
will push that to my new squares array
so i'll say new squares.push
updated square
however if the id is not the same so
i'll say else we're just going to simply
push
the current square
to our new squares array
at the end of this for loop we should
end up with an array that looks almost
identical to the original array proved
squares however one of the items should
have a flipped value for its on property
and so we can see this is getting a
little bit long but there's my for loop
at the end we'll simply return because
that's what we need to do from our set
squares function is return the new value
of state we'll return our new squares
array to be totally honest i haven't
tested this out let's hit refresh see if
this works oh look at that awesome
let's walk through exactly what this is
doing let me clean up my challenge to
buy us some room here every time i click
on one of these squares it's running the
click event handler that we defined here
that click event handler is running the
toggle function that it received through
props and passing in the id that it also
received through props that toggle
function is taking that id
running set squares
and running this function to determine
what the new square should be
we look at the previous array of squares
and simply generate a new array loop
over the previous array and when we run
into the square in our loop where the id
matches the id passed into toggle
we create a new object that will replace
the old object and push that to our
array
if the ids do not match we just push the
current square in its current form
without any changes made to our new
array
and we return that
by returning this new array react will
update our square's state array which
means that it will then re-render this
component
remap over all of our squares and create
six new box components
pass the on value which was the same in
five of the squares but different in one
of them and then in our box component it
will simply take that prop and determine
what the background color should be
all of that seems really complex i
totally understand that but you can see
it's quick and there really is no lag in
doing this at all
at this point we could just move on from
this let's say it's a feature we're
adding to some app we're creating
however as we've learned react really
adheres to the principle of writing
declarative code
what we have here is very imperative
doing a c style for loop this way works
perfectly without any problem so if
you're happy with this you can just move
on but i think it might be worth our
time to take a look at how we might
write this slightly differently using
something a little more declarative
instead of imperative so that's what
we'll do in the next lesson
i'm not going to bother making this a
challenge this time i think i'll just
walk you through how i often times will
update an item in an array using a more
declarative method instead of using a c
style for loop like we have here so let
me go ahead and just delete everything
inside and i think what i'll do is use
the dot map method to help me create a
new array and return that array all in
one go so i can say return
the previous squares dot map and
whatever i put into my map function here
is going to help determine my new
version of the array which then gets
returned from my dot map and returned
from set squares this is a lot of
returns happening all in one but let's
just see how i would do this i need to
look at each square inside of my map
and whatever i return from this callback
function inside of my dot map is what
will get placed at the same index in my
original array in the new array that i
return so what if i were to use a
ternary that said
does square.id
match the id passed into my toggle
function
if so i want you to return a new object
that has all of the properties of square
except for the on property which is the
opposite
of square
dot on
however if the id does not match that's
my else here then i can simply return
the square the only thing i'm missing
now is the return keyword i tried to
leave it out in the beginning because
these two returns can be a little
confusing at first
so fingers crossed let's hit save and
look at that everything is updating
beautifully obviously what we have here
is a lot more concise in terms of lines
of code but it does require a bit more
of an advanced understanding of
javascript to fully comprehend in my
experience what i have here is not so
clever that other software engineers
would not understand it and therefore i
personally would prefer a solution that
looks more like this i would definitely
spend some additional time understanding
this if this is confusing but i will
walk us through it one more time
every time box gets clicked it runs this
function not just props.toggle but this
function that we've defined inline here
that function will run props.toggle
remember we did that so we could pass a
parameter a custom parameter to
props.toggle which we decided to be the
id of the box itself then if we go over
to the toggle function
it will call set squares our state
setter function
and we need to use the callback function
version of set squares because we do
care what the previous array looked like
so we look at the previous squares and
we're going to map over those squares
as a reminder.map returns a new array
without modifying the original array
that will have the same length as the
original array
and whatever we return from the callback
function of dot map is what will get
placed in the same index in the new
array as what was in the original array
what we're doing every time we loop over
an item in this array is we're checking
if its id matches the id this id here is
the id that we passed into our toggle
function
if those ids match then that means it is
the square that was clicked if that's
true then i want to replace the old
object with a brand new object which is
why i have these curly braces here and
this is crucial so that i'm not updating
state directly this object is going to
pull in all of the values of squared
exactly as it was but then it's going to
overwrite the on value with its opposite
however if this is not the box that was
clicked then just give me the old square
in this case because i'm not making any
modifications to it i don't need to
create a new object and spread in the
old square or anything like that i can
just hand the old square object directly
to my new array awesome work i really
hope you were able to follow along with
that logic this truly is something that
just takes a lot of practice
at this point one of the very best
things you could do is just delete our
toggle function completely and try to
recreate it from scratch
in the end this toggle function is the
most complex part of what we have here
so that would be a great place to start
if you really want to challenge yourself
i did want to show you one other rather
clever solution that we could use
instead of passing an id down to the box
and that is that we could just say our
toggle function that we're passing down
just like we did inside of our box
is going to be an individualized toggle
function this entire function here
however
we can pass the square
dot id
immediately as we're passing this toggle
function down in essence this creates
something called a closure where each
instance of our box will have its own
toggle and it will remember its own id
which means i can get rid of this id
prop and over in box i can change this
back to just toggle or rather props dot
toggle if i hit refresh
we can see that it's working exactly
like it was before
again awesome work i really hope that as
you have followed me in this mini series
on setting state and creating this
rather silly little app that you have
worked on the challenges that i've given
you if you haven't it's not too late
don't just push forward go back and work
on these challenges make sure that you
really understand everything that we've
done so far pushing forward without
understanding this is not going to help
you it's only going to make it harder
going forward spend the time now to
really clarify these things ask
questions in the scrimba discord and
then when you really understand it you
can be happy knowing that you are ready
to move forward
okay well this might look familiar this
is our joke component from the previous
section and we're going to use this to
kick off a sort of mini series on
learning about conditional rendering in
react
using and understanding conditional
rendering is very important in react
because you will see it everywhere in
react code to start us off i have a
challenge for you you're going to create
some state called is shown its value
will be a boolean and you'll just
default it to false the idea is for it
to be a piece of state that will decide
whether or not the punch line should be
shown in each of these jokes and then i
want you to add a button probably just
right here below the paragraph that will
toggle that is shown value back and
forth pause the screencast and work on
this challenge
at the top of my component i'll
have my state called is shown
and set is shown
that'll equal react dot use state the
default value will be false
and then we'll add a button
let's have this say show punchline
then let's create a function that will
help us toggle our
value back and forth we'll just call it
toggle shown and all it's going to do is
run set is shown
we do need to know what the previous
value of is shown was so i'll say prev
shown and that way we can return the
opposite of preview shown that'll just
flip it from true to false or false to
true and let's add our on click event
listener here to run toggle shown
while we're at it i'll go ahead and
console.log the current value of is
shown
and when i click show punchline okay now
you'll notice that it said false even
though i'm flipping it that's because it
first console logged is shown which
initialized as false and then i called
set is shown if i click it again i'll
see the old value right before it got
changed this console log's not terribly
important anyway so we'll take it out
one of the reasons i use this joke
component to help us learn conditional
rendering is well i used it already as a
way to give you a sneak peek into
conditional rendering since we have a
template here already even though this
might seem a little backwards i want you
to make it so that our paragraph here
only shows up if is shown is true again
you have a template to help you
understand how that works and then once
you have that working we'll talk through
the logic and really fully understand
exactly what's going on let me update
our challenge text here
okay make it so that this paragraph only
displays if the is shown boolean is true
pause the screencast and work on this
challenge
well as we see here what we did is we
surrounded everything in curly braces
and that allows us to put a javascript
expression in here
in our case we're going to say if is
shown is true
and this paragraph
first let's see if this is working
okay all of our paragraphs our punch
lines are gone
and if i click show punch line awesome
our paragraph displays now why on earth
does this work when you first learn
javascript we usually learn about how
this and logical operator the double
ampersand is used to make sure
that both sides are true or truthy so
let's say you have a couple variables
we'll say condition one we'll call it
true and condition two let's say that's
also true
if you have an if statement that says if
condition one and condition two meaning
if both of those are true or truthy then
the code inside
this code will run
we also learned that if either one of
these are falsy or false so if i change
either one to false
this code will not run
however if we look deeper into how the
computer is actually running this code
it can be very enlightening for example
let me change condition 2 to a console
log statement this is kind of a strange
thing you're not really going to see
this in the real world but it's just to
prove a point
say hello there let me open the console
and i'm going to click save and we'll
see that we immediately get the console
log running of hello there
now let's see what happens if i change
condition 1 to false
i'll hit save and nothing gets console
logged that's because what the computer
does is it first checks the truthiness
of this first statement and if it is not
truthy if it's false or falsy it
actually completely skips whatever it
sees after the double ampersands
since it already knows that this
condition will not satisfy what the and
is expecting in other words for both
sides to be truthy it knows already that
it can completely skip whatever it sees
here
so we can take advantage of this in
react anytime we have an element on the
screen that we want to display if
something is true or completely hide or
not even render to the page if that
thing is false
here with the setup we realized that
some jokes were just one-liners they
didn't have a setup and a punch line
they just were the punch line and in
that case we looked at our incoming
props.setup and said if that's falsey
then don't display this h3 at all
similarly with our local state of is
shown we can say i only want to display
or render this paragraph if is shown is
true
by doing that we can have a toggle
button that when it's clicked will
change is shown of this individual joke
component to true and therefore it will
display
our paragraph more specifically when i
click this button react will re-render
this component because its state has
changed and therefore when it's running
the return value again and determining
what should actually be placed on the
screen is shown is now true and
therefore this expression gets run and
put onto the page for us so as a recap
in react when you have an element that
you either want to display or not
display at all using the and logical
operator is a really concise and great
way to do that
this challenge is a pretty
straightforward one based on what you
just learned using the and logical
operator make it so that this h1 will
only display if our array of messages is
not empty
if this array is empty then this h1
should not display at all and we should
end up with a blank page
while you're at it go ahead and fix our
little underline for the number of
unread messages we have in our array
pause the screencast and work on this
challenge
well first let's replace this underline
we can put in a set of curly braces and
simply say messages dot length
okay that's a good start now if we're
deciding whether we want to display this
at all or not then we can use the
logical and operator to say messages
that length
is greater than zero
and
display this h1 that way if
messages.length is greater than zero is
a false statement in other words if
messages.length is equal to zero then
this h1 will simply not render at all a
more concise way might be to just say
messages dot length and this h1 and
that's because the number zero is
considered a falsy statement however i
think it reads a little better to be
explicit and say the greater than zero
there sometimes if this line gets a
little bit long you can break it out
onto its own line something like this
and we can test this by emptying our
initial state array and there we go we
have nothing on the screen
awesome work next we're going to see
another method for doing conditional
rendering in react
we have a funny ui bug right now when we
click show punch line it shows the punch
line but the button still says show
punchline knowing what you know so far
using the and operator to conditionally
render something i want you to think for
a second how much you change it so that
it says hide punchline instead of show
punchline when the punch line is shown
one thing we could do is make a copy of
this button and display them at
different times so i'll do my similar
conditional rendering and say if if
shown is true
then i want this to say hide punchline
and if is shown as false or if not is
shown
then i want this to say show punch line
technically this will work so it says
show punchline and then it changes to
hide punchline however we can do better
than this and we can do so by using the
ternary operator returnery is really
helpful when you want to display one
thing based on a condition
or another thing if that condition is
falsy
so instead of duplicating our button i
can keep my button here and simply
change the word from show to hide using
a ternary let me show you what that
looks like i'm going to delete the word
show put in a set of curly braces
because i want to use javascript now and
we're going to use a ternary looking at
the boolean value is shown and i'll say
is shown question mark now if is shown
is true then i want the string hide to
be displayed at this point in the button
otherwise i want it to say show
i hit save
it's showing show punch line and when i
click it it changes it to hide punch
line
as far as conditional rendering goes
probably 95 of the time you will see
conditional rendering handled with
either the double ampersand or a ternary
again the double ampersand is great if
you either want something to display or
not display and the ternary is great if
you want to choose between one of two
things to display
if your conditions are more complex than
just having one of two options to
display usually it'll be best just to
turn to a regular old if statement as we
have seen in the past you can save a
variable for your text and do either a
switch statement or a series of if else
if else if else statements to determine
what that variable should be and then
just display it in your return down here
below since we've already seen what that
looks like in the past i'm not going to
cover it now i mostly just wanted to
look at these two methods for
conditionally rendering something in
react now that we've learned that let's
get a quick practice in
let's do some conditional rendering
practice one thing i've done with our
messages app is i changed this to just
say messages instead of num messages
because well that just makes more sense
because this is an array of messages not
a number of messages anyway your
challenge is to display the correct
thing on the page if there are no unread
messages it should display you're all
caught up and if there are any messages
in the array it should display you have
n unread messages where n represents the
length of the array or the number of
messages in that array as a caveat
though notice i put this parenthesis s
here that's not literally the text
parentheses s instead i want you to if
there is exactly one unread message put
the word message there instead of
messages
so pause the screencast and work on this
challenge
there certainly is more than one way to
accomplish this for example i could
always render an h1
and then use a ternary inside for the
text of that h1 for some reason that
doesn't sit quite right with me i'm
honestly not sure why but i think the
way that i would choose to do this is
just to open my curly braces look at the
messages dot length and say if that is
exactly equal to zero and here i'm going
to use a ternary so i'll start a
question mark on the next line this will
be what should display in case there is
exactly zero messages so i'll do an h1
here
and say
you're all caught up
otherwise
i'll put a different h1
that says
you have
and let me just put the number
hard-coded here for a second
unread
messages
okay i'll replace this two with
messages dot length
and well let's see where we are right
now i'll hit save
you have two unread messages if i remove
the items from the array
you're all caught up awesome
at this point it might be tempting to do
some kind of nested ternary here that
says if messages.length
is exactly equal to one and put another
ternary as the else of this first
ternary personally i think this is
nearly impossible to reason about and so
i never do nested ternaries myself i
suppose one thing i could do is just
render this s if messages.length is
greater than one i think that would look
something like this i would put message
and then a set of curly braces and put
in my
javascript here that says messages
that length is greater than one
and
the string s
let's just see if that works personally
i don't love this solution i'll add in a
couple items here
okay we have two unread messages and if
there's only one item
okay you have one unread message however
when i look at this it's not quite as
clear as what i think i would prefer to
do and that is to type out the whole
word message or messages and use a
ternary let me show you what that would
look like you have
blank unread and then i will open up
some javascript here
and say
is messages.length
greater than one
if so i want it to say messages but
otherwise i just want it to say message
i'm going to put this onto its own line
just so we have some extra space and
although this does take up more
characters i think than what i had
before to me this is a lot easier if i
have a fellow developer who's going to
be coming onto this project and needs to
understand what i'm doing here i think
this is easier to reason about and
understand as you can see there are
multiple ways to use conditional
rendering and this is the kind of thing
that i'm talking about when we say that
react is just javascript just like in
javascript where there's multiple ways
to solve a single problem it's the exact
same in react because you're just using
javascript like ternaries and the
logical and operator and so forth you
truly could solve this in probably
dozens of different ways
most people will tell you to find a way
that is easy to think about in the
future and then to stay consistent
throughout your entire code base
let's go ahead and test this before we
call it a good solution
and yeah see i need a space there so
we'll put
an extra space in there
oh and i guess breaking this onto its
own line might not have worked so let's
just leave it like that okay one unread
message
and
two unread messages
awesome work when you're ready let's
keep moving forward
it's that time again for another quiz
pause the screencast click into the
editor type your answers down and when
you are satisfied with your answers
click play and we'll go through the quiz
together
number one what is conditional rendering
conditional rendering is just a way to
determine whether or not something
should get displayed or as we're going
to see what among many choices should
get displayed
unlike a regular html page which will
always display whatever you hard coded
into the html with react we can use
conditional rendering to sometimes not
display that thing or to sometimes
display one thing instead of another
so conditional rendering is when we want
to only sometimes display something on
the page usually based on some sort of
condition or maybe i should say always
based on some sort of condition
so far we've learned a few different
ways to handle conditional rendering
when would you want to use the double
ampersand or the and operator the and
operator is great to use if you want to
decide whether or not to display
something at all
so in other words when you would want to
either display something or just not
display it at all in that case what you
put before the and operator is the
condition
and if that condition is true or truthy
then the jsx element that you put on the
right side of the and operator is what
will either get displayed or not get
displayed based on the condition of the
thing on the left of the and operator
number three when would you choose to
use a ternary where the and operator is
great for deciding to display or not to
display something a ternary is great for
deciding which among two things you want
to display
technically speaking you can nest
ternary operations inside of other
ternary operations but personally i
highly recommend not doing that if you
find yourself needing to choose between
more than two options you probably
should just be using regular
conditionals with if else if and else or
possibly a switch statement and well i
guess i just answered number four so if
you do need to decide between more than
two options you should use a regular
conditional statement using if else if
and else or a switch statement
there's one slight difference between
the and in ternary and what you can use
with an if else if else block and that
is that the and and the ternary can
happen directly in line inside of the
returned elements of your function
whereas with the if or else if or the
switch statement those will have to
happen outside of the return of your
function so if i have a functional
component let's say it's app
and i'm returning some kind of ui
the and and the ternaries can happen
right here in line so i can have
something
and some jsx
or i could use a ternary that has the
condition
and the ternary and then an else
inside the ternary which is some other
element but if i need to use an if else
if and else or a switch statement i
can't do my if inside of the jsx
directly like this instead i need to go
up above i can set a
variable and then use my if
and else if
and else block to set some variable to
some kind of jsx
i won't type out the whole thing but
that allows me to then just inside of
here display some variable because
previously in my if statement it was
determined which jsx element it should
be
great work on this quiz we still have a
lot left to learn in this section so
let's keep moving forward
we're going to spend a fair amount of
time talking about how to manage and
deal with forms in react from the
outside this might seem like a kind of
strange segue for us to be taking
however i have found that forms are one
of the most difficult things to
understand and truthfully one of the
most difficult things to use in react if
someone were to ask me what i think is
one of react's greatest weaknesses i
would probably say forms fortunately
there is a plethora of really awesome
form libraries out there that in my
experience many people end up turning to
in order to manage forms and not have to
build everything that we're about to see
and learn about from scratch however
that being said it is really important
to know how to do this because
especially when you're dealing with a
really small form like what we're about
to see in the meme generator it's not
that difficult and once you get enough
practice under your belt it's pretty
straightforward so why are we talking
about forms in the first place well in
the old days you would create a form in
your html and you would give it an
action which had the url usually of some
kind of php file that would process your
form you would give it a method usually
of posts and then when your form was
submitted through some sort of submit
button your php would pick everything up
from there and process the data from the
form fast forward a little bit to
slightly more advanced javascript but
still vanilla javascript and you would
likely see something that looked kind of
like this
this selector goes and gets the form it
adds a submit event listener
and the function that runs whenever the
form is submitted would simply gather
all the values together and then submit
it to an api somehow of course my
function is just console logging stuff
if i were to type in a first name and
last name here let's put joe
schmo
and it's just console logging our data
the main takeaway here though is to know
that when you're submitting the form it
would gather all the data immediately at
the very end of the process and then
submit it immediately after gathering it
so how is this different from react the
main difference in react is that instead
of waiting until the very end of the
process and filling out the form when
the form is submitted and then gathering
the data instead what we do is we create
state and every keystroke change or
checkbox change a radio button change or
whatever it might be we update state and
therefore we are watching these inputs
every keystroke or every change that's
made to our form then when the time to
submit comes there's no more work really
to be done we already have gathered the
data and we simply submit that to our
api and pass in the state that we have
been tracking all along
coming up we are going to jump into the
specific syntax of how to do this
however i really think it would be a
good idea to sort of pregame for these
lessons by reading through the react
documentation on forms i know forms can
seem like a rather mundane topic but i
promise this documentation from react is
really excellent they've done a great
job explaining it think of this like
reading the textbook before coming to
class once you've had a chance to at
least skim through the documentation and
gain some level of understanding on
forms and react you'll be ready to move
on to these next lessons where we start
learning about how to deal with forms in
react
let's see how we can manage these forms
in react and we're going to start very
simple with a single input i'm keeping
this as simple as possible so not to
distract us from anything but learning
forms as a reminder in vanilla
javascript we would have a submit button
and when we clicked that submit button
it would run a function gather all the
data at that time and then submit it to
an api or wherever what we'll be doing
in react instead is maintaining
up-to-date state for every change that
happens in any input in our form to
accomplish this there's a few things we
need to do first of all we need some
state to hold the current data that's
typed into our input just like we've
been learning i can say
let's say first name and set first name
is equal to react.use state
i will set an empty string as the
default because i would expect my input
to be an empty input box in the
beginning and now what i need to do is
listen for any changes that happen to
this input can you think what event
listener i might need to add to my input
to accomplish this
most or all form elements have an event
called onchange and i can set that equal
to a function let's call it handle
change which i obviously haven't
declared yet so let's declare that
function
and for now let's just console.log
changed
i hit refresh and now we can see every
keystroke that i make is running our
function now one thing we haven't spent
much time talking about is this
parameter that i can actually receive as
a part of my event listener function in
this case i don't get to decide what
actually gets passed to my handle change
event listener function instead what
will get passed to it by the browser is
an event object
this event object is really large it has
a lot of information in it and if i
console.log event in scrimba it's simply
going to put synthetic base event so at
this point i'd recommend you actually
open your developer tools in the browser
and see exactly what got logged to the
console you'll be able to dig into all
of the properties of this event object
however there's one property in this
event object that i care the most about
and that is one called target if i log
event dot target we'll see that it gives
me what scrimba shows is the html
element that triggered this event now it
looks like html in the console down here
but in reality it's just the dom object
that triggered this event that dom
object has properties that we care a lot
about for example the value property let
me hit refresh and i'll just start
typing letters and you can see in the
console we're logging the current value
on every keystroke of that specific
input box
so let me set up a quick challenge for
you
your challenge is to update the first
name state on every keystroke i've set
everything else up for you you should be
able to complete this challenge fairly
quickly i've added this console log here
what this will do is every time the
first name state changes it will
re-render your component and therefore
it will rerun this console log this is a
really simple way for you to see that
everything is working assuming you hook
everything up correctly in our handle
change function this console.log line
should fire every time you type into the
input box pause now and work on this
challenge
simply enough we should be able to use
the set first name state setter and in
this case i don't really care what the
state used to be or rather i don't need
to know what the state used to be in
order to determine what the state is
about to be because i have quick and
easy access to the information that's
currently typed into the input box by
accessing event.target.value
so i should be able to get rid of these
lines
i'll hit refresh
and i'll start typing in my input box
and sure enough our state is updating
with every keystroke
and there we have it as you can see at
least starting out this isn't that
terribly complicated however i am about
to throw some wrenches in here we're
going to see that the complexity level
will rise a little bit however before i
do that i want to get your hands on the
keyboard and we'll do that as part of a
challenge
in this challenge we want to add a last
name input to our form as i've done
before i'm being a bit intentionally
vague here and that's so that i can get
you to think of all the steps that you
would need to run through in order to
get this to work so do your very best in
this challenge and when you feel like
you've got a good solution you can hit
play and i will show you how i would do
it pause now and work on the challenge
as you worked on this challenge you
might have started to see places where
we were not being dry in our code in
other words we were repeating ourselves
quite a bit for example i could
duplicate this line and i will change
first name to last name
we'll say set
last name
i then could duplicate my input
and we'll change this to last name now
of course there's a problem with using
the handle change function on change and
that is because well handle change is
only changing the first name so maybe we
make a change that says handle
first
name change
we'll update our on change there
and then we'll duplicate this function
and handle last name change you can
probably see where i'm going with this
and how this is not going to be the
ideal solution
and then last of all we need to change
this to set last name
i'll add a console log here just so we
can see if things are working the way we
expect we'll look at both the first name
and last name
we'll hit save start typing we're
looking at joe
schmo
okay
of course this seems to be working but
we can clearly see this is not ideal
especially when you think of some of
maybe the crazy forms that you filled
out before that have let's say 20 or
maybe even upwards of 50 input boxes
it's not going to work great for me to
have a separate change function for each
one of those and a separate piece of
state for each one of those so next what
we'll do is we'll learn how to combine
our state into an object and how to use
the event parameter that we're receiving
in our event handlers to determine which
property of that state object we should
be updating so when you feel confident
with everything that we've worked on
here let's jump into that next
let's see how we can improve our form
and how we're managing state so that
when the time comes to add let's say 20
or 30 more inputs we don't end up
drowning in duplicated code now if you
do just have two or three maybe even
four pieces of data in your form that
you care about doing something like this
might be okay or at least manageable
once you get to four or beyond however
it starts to make a lot more sense to
save your state in an object instead of
in separate variables a benefit of doing
that is we'll receive one setter
function which we're going to learn how
to use to update the correct piece of
state in the object let's just dive into
the syntax to make more sense of this
i'm going to remove this extra function
here let's change this back to handle
change so we can figure out a way to
make it more universal and i'll set my
on change to work for both of those
let's also get rid of our extra piece of
state here and instead we're going to
choose to save an object as our default
and that object will have a first name
property as an empty string and a last
name property as an empty string
let's move this onto its own line
then i'll change first name to something
more generic like form data and set form
data
lastly let's get rid of this so that we
don't have broken code
and awesome this is a good starting
place
if you remember back when we talked
about the event that we're receiving in
our handle change event listener
function if you did spend some time in
your developer tools poking around that
object and looking at its properties you
probably saw event.target which we
talked about in that previous lesson
now in scrimba if i console.log this
event.target it gets a bit truncated to
look like an html element however under
the hood it's really a dom object that
we can access properties on
in fact we saw how i can look at the
value property to get the specific value
that was typed into the input box
however at this point because an object
is what we're saving in state i can't
simply say set form data to
event.target.value because that would
erase my object and replace it with just
a simple string and because i'm using
the same handle change function on both
of my inputs i need a way for the handle
change event to distinguish between
which input it was that triggered that
event well it turns out that a good
practice that we're neglecting to do
right now is to give each of our inputs
a name property this is true of regular
html forms in any case but in react it's
going to play a special role for us what
i can do is make the name property match
exactly the property name in the state
that we're saving in fact a good idea is
to just copy and paste it so that you
don't misspell it
and now i have access to
event.target.name
let's hit save i'll trigger the event to
happen in the first name property and
you can see it logged the first name
property there if i do it in the last
name it logs last name
well this is a great start we have
access to the property of state that we
want to change and we still have access
to
event.target.value which is the value
that we want to change it to so now we
have everything we need to call set form
data and update our object correctly
let's go ahead and call set form data
before when we were simply updating a
string we didn't care about what the
previous version of that string was
because we were just going to overwrite
it with whatever was in the input box
this time around however we do need to
know what the old version of state was
because we have a lot of other
properties well in this case we only
have one other property but imagining a
larger form we have many other
properties that we need to maintain
instead of just overwrite so i'll do a
callback function in here i'll use an
arrow function and call my previous
state let's say prev form data
i'll use an arrow function and open up
the body of that function my goal is to
return a new object and i want to make
sure i keep all of the old object intact
so i'm going to spread out the previous
form data but then i'm going to
overwrite the specific property that we
are trying to overwrite or that we're
trying to update in this handle change
event listener well on your first
attempt the inclination might be to try
something like let's use
event.target.name as the key
and event.target.value
as the value of course as we can see in
the editor this is a syntax error
however with es6 there is a feature
introduced called computed properties
and what this allows me to do is to
surround my key here in square brackets
long story short it makes it so i can
turn a dynamic string like something
saved in a variable and use it as the
property name for my object if that
doesn't make a whole lot of sense don't
worry too much just know that you can
fix the syntax problem by having dots
here by surrounding it in square
brackets
that's an overly simplified way to
describe it but don't worry too much
about that that's not the important part
to take away from this lesson let me add
back my console log
so we can look at our state every time
it changes
hit save we can see in the console that
it's empty to start with and as i change
the first name my object is updating
correctly my last name is also still a
part of my state as i update the last
name awesome this is great news that my
entire state is staying intact honestly
what we just learned in this lesson
might be one of the most difficult parts
of understanding forms in react so for
those of you that were able to follow
along awesome good job for those that
were struggling still that's completely
okay and completely normal don't be
afraid to go back re-watch this a few
times and because of that in the next
screencast we're going to practice this
a little bit more
hopefully in this challenge you'll get a
chance to see why it's beneficial to
structure things the way that we just
learned how to do your challenge is to
add an email field and associated state
to our form pause the screencast and
work on this challenge
previously when we were saving all of
our state as strings anytime we wanted
to add new state we needed to create new
variables and new event handler
functions
now however we simply need to add a
field to our state object here we'll add
an email property that starts as an
empty string and as long as with my
input i give it the correct name i
really don't need to change anything
about my handle change function so let
me add another input here i'll just
duplicate this one
for good measure i'll change the type to
email
of course we'll change the placeholder i
don't need to change my onchange
we'll make sure that this name exactly
matches the name that we chose in state
on our property here
and well i believe that should do the
trick i'll hit save
type in a first name we'll say it's joe
last name schmoe
joe at schmo.com and sure enough our
state is updating exactly as we would
expect now maintaining all three of
these properties
now for those of you that followed my
directions a few screencasts ago and
actually read through the react forms
documentation you would have come across
a section that talked about controlled
inputs as of right now our inputs are
not controlled and so in the next
screencast we're going to see one simple
addition we can make to turn them into
controlled inputs and we'll talk briefly
about what a controlled input is in the
first place
a term you might hear floated around as
you're learning about react is something
called controlled components again if
you read through the react forms
documentation you'll have come across
the section called controlled components
if it's been a minute or you didn't have
a chance to read through that you can
click this slide in order to go directly
to that documentation but when we're
talking about maintaining state inside
of a component there's a common concept
called the single source of truth the
idea is that the state that you're
maintaining in your component should be
the single source of truth if you think
back to when we were learning about
changing state and we had our boxes or
squares example one solution we came up
with was allowing each box to take the
incoming on prop and then set its own
internal state based on that incoming
prop
and then the box itself could change its
own internal state and therefore display
either being filled in or not filled in
if it's been a minute since you've seen
that lesson of course you can always go
back and watch that too refresh on what
i'm talking about here the problem as we
learned then is that we have two
instances of that state that exist and
they don't necessarily match up in other
words there isn't a single source of
truth the array of these objects was
being held in state in the app component
however each box was then changing that
state essentially without telling the
app component that it was changing and
therefore there was state that
oftentimes would not match with one
another we have a similar concept
happening here where in the markup
inside of our inputs each of these
inputs in effect is holding its own
state think how in a regular html form
no react involved at all when a user
types into an input box essentially that
input box is maintaining its own state
well in this case we have two pieces of
state one is being held by the input box
just in regular html and the other is
updating on every keystroke held in our
react code
of course we have set it up so that the
state of our input box then perfectly
gets mirrored by our state in react
however a good practice in react is to
make it so that your react state is what
drives the state that's visible inside
the input box
i totally understand this might seem
like i'm splitting hairs here but if it
helps all this really boils down to is
simply adding a value property to each
one of our inputs so here at the bottom
of each one i'll add value equals and
then a set of curly braces and then all
we need to do is add the piece of state
in other words form data dot and then
the name of that specific input into
that value so we'll add form data dot
and then in the first one i'm going to
have
first name
last name
and email
visually we're not going to see any
difference here conceptually however
when i type into the first name bob the
value of this input box is no longer
being controlled by the input but rather
by react every change that i make runs
my handle change function which then
updates the correct piece of state which
re-renders my form and it sets the value
of my form input to be whatever state is
so now state is in the driver seat
telling the input box what to display
rather than the input box telling the
state what to be
the main reason to learn this about
controlled components is because
sometimes if you don't set this up
correctly react might sometimes complain
about having uncontrolled components
fortunately the concept itself is more
difficult to understand than actually
implementing it so if you don't feel
like diving deep into understanding
controlled components honestly that's
going to be completely okay at this
point just remember that you need to set
the value of your inputs to be equal to
your state that represents that input
value there are a few more small things
that we need to learn regarding forms so
at this point we're going to speed
through some of those so that we can get
to a challenge that will help you
practice all of this together
if only all form elements were as simple
and designed the same way as the inputs
that we've been working through these
text based inputs then our life would be
so much easier however forms have more
variety in the types of inputs you can
have for example radio buttons and check
boxes text areas and so forth each one
of these has some special considerations
we need to keep in mind when we're using
them in react to start us off let's look
at the text area element
in regular html text area is a little
different than an input because it is
not self-closing it has its own separate
closing tag and in html whatever
you put inside the opening and closing
tags is the value of that text area
you'll see i'll hit refresh and we get a
text area that's a little bit larger we
can also set the size with rows and
columns the user can make this bigger or
smaller if they need to
however what the react team has done is
they've chosen to make the text area
much more similar to a text-based input
and so they've taken the closing tag
away they've made it a self-closing
element and just like our inputs we will
now add a value property to it and
that's going to be the value that's
inside of the text area
once you understand that they've changed
the text area to be a self-closing
element essentially everything else
we've learned about text-based inputs
remains the same
i suppose in the text area case we're
probably not going to include a type
because the text area is sort of its own
type already but everything else should
essentially be the same as our inputs
which means that it's time for a
challenge
okay your challenge is to add a text
area for comments to the form we do want
to include these comments in our state
as the user is typing into the text area
itself so make sure to update our state
as well
pause the screencast work on this
challenge
while we're up here with our state i'm
going to add a comments property to my
state object and initialize it as an
empty string then at the bottom of my
form i'll render a text area element
again it's self-closing
and just like the other ones we will put
a value in here that will be
data dot comments that way it can be a
controlled component
we'll add a placeholder
that just says let's just say comments
we'll use the same on change handler so
we'll have handle change
and in order for handle change to work
we need to make sure we assign the same
name that we have in state so comments
and comments
now i've added some styling i did that
directly to input so my text area isn't
going to be styled that way maybe i can
get lucky and just
add text area directly to my styles here
let's hit refresh
and okay well my height's a little funny
but that's something i could always
change later let me add a console log
here so i can make sure that it's hooked
up correctly to state we'll just log
maybe we'll just log form data dot
comments to make sure that just that one
piece is coming in
okay
awesome
oh i guess those styles aren't really
going to work out because it's doing
that text indent thing that's kind of
silly let's just put this in its own
thing
okay that's a little better
awesome job the next form element we'll
talk about is check boxes
let's take a look at the checkbox
element now checkboxes aren't just an
html element on their own called
checkbox although to be completely
honest i kind of wish they were because
that would just be a lot easier but no
they are an input with a type of
checkbox
checkboxes are fundamentally different
than what we have been working with so
far with our text inputs because they
just hold boolean values in other words
there's not going to be some kind of
string text of my checkbox instead there
is a checked property that will either
be true or false based on whether the
user has checked the box or not
before we jump into check let me clean
up my input for just a second because
right now i just have a bare box sitting
here
while i was cleaning up this check box i
was reminded of something that we
haven't yet talked about and that is
this html4 property when we have
something like a label that is supposed
to be tied to another input you have a
couple options you could nest the input
directly inside of the children of the
label what that does is if the label
gets clicked it will automatically
propagate that click down to the input
however my personal preference is to
keep the label as its own separate
element and then point that label using
html4 to the id of an input so that they
can be associated with one another in
plain html you're probably used to using
just four but if you were to look under
the hood at the underlying dom element
it's really called html4 that's the
javascript property for that element
anyway that's a digression so now we
have a checkbox that asks the person if
they're friendly or not
and we want to maintain this in state
well because it's a checkbox we're not
maintaining a string so up in state i'm
going to add another piece of state and
actually start separating these onto
their own lines to save some space here
and we'll call it is friendly and just
to give them a benefit of the doubt
we'll call it true as the default as i
briefly mentioned to associate our state
is friendly with our checkbox we're not
going to use something like a value
property
but instead we're going to use a checked
property
now because a checkbox is either checked
or unchecked the value that we put in
here for checked needs to be a boolean
or at least whatever you put in will be
interpreted as a boolean so if i put
something truthy in like the string hi
it's going to check the box if i put in
something falsey like an empty string
it's going to not check the box but in
the end that doesn't really matter
because this should be a boolean value
so i'm going to say form data dot is
friendly now when i hit refresh do you
think that this checkbox will be checked
or unchecked
it should be checked because our default
value is true
right there
so when we say this box has checked we
are having react dictate to the box that
it is checked in fact because that's
what state is of course now we've
introduced a bit of a bug i can't
uncheck the box
maybe that's a good thing for this
specific form we don't want people to be
unfriendly but for the sake of argument
let's say we want this to act like a
normal form if we look closely at our
handle change function we have only been
looking at event.target.value
however with a checkbox we are not
looking at the value property anymore we
are looking at a checked property so of
course i could go out of my way to
create a completely separate handle
checkbox change function but we can do
better than that let's assume for now
that we can reuse our same onchange
function we'll put in handle change as
our unchanged and then let's go up to
our candle change and we're going to
make some modifications here the first
thing i want to talk about is a best
practice that we should be following and
that is not to put the entire
event.target.value and event.target.name
down here inside of our set form data at
this point in the course it's not that
important that you understand why we're
going to do this but a much better way
to handle this is to restructure
event.target and pull out the values
that we need
so we need name and value from
event.target
and then i can switch this to name and
switch this to value
and then as i mentioned when we're
handling a checkbox there's a few more
things we need to pass in one property
that will come in is this type property
on all of our inputs we have a type text
email and down here our type of checkbox
so let's bring in that type so we can
check whether or not the input that's
making this handle change function run
is a type of checkbox and if it is we're
also going to need the checked property
and this is either going to be true or
false depending on how the user has
interacted with the checkbox now comes a
bit of a trick when i'm setting my form
data i want everything else essentially
to be the same however the piece of
state that i want to update if it's a
checkbox in our case the is friendly
property should not take on value but
rather should take on the value of
checked so i can use a ternary here that
says is the type
equal to checkbox
if so i want you to use the checked
property
but if not i want you to use the value
property let me get rid of this console
log because that's from a previous
screencast let's refresh we'll hit the
checkbox and oh no there's a bug so i'd
like you to look at the input that we've
created perhaps compare it to some of
the past inputs that we've created and
see if you can figure out what we're
missing
all of our other inputs have a name
property and that's something that i
simply forgot to add in so i'm going to
add a name this needs to match exactly
what is in state say is friendly and
that way when i hit refresh i should be
able to now check the box awesome this
is probably a good time to mention that
everything we're learning here with
forms can be really confusing and
especially hard to try to memorize
honestly as i've been preparing this
lesson i've had to go back to some of my
old notes and some of my own recordings
to remember what the syntax for this
actually looks like so just think of
this as a pep talk now if as i'm
teaching it you're still feeling totally
lost and it's not making any sense at
all that's a cause for alarm you should
be able to generally follow along but in
this case i'm not necessarily going to
quiz you on the exact syntax for
everything because well it's just as
easy to look it up if you really need to
okay so let's get back on that horse and
we're going to next look at radio
buttons
in react radio buttons are kind of an
interesting combination of check boxes
and text inputs i'll talk about what i
mean in just a second but in the
meantime i've put together this field
set that asks about our current
employment status to skip some of the
mundane stuff i've already added the
type of radio and some ids in order to
associate the labels using html4 with
the correct inputs so now let's talk
about how we can hook these radio
buttons into our form and connect it
with our state
first we need a place in state to hold
all of this information i'll add another
property to our state called
employment
and where check boxes are either true or
false radio buttons similar to inputs
will have some kind of text value to
them in this case i want employment to
be some kind of string either unemployed
part-time or full-time so on a high
level overview what will happen is when
the user clicks one of these options we
will be watching for changes in these
inputs and when a change happens it will
take the value of that specific radio
button that was clicked and set our
state to that value in order to
associate my inputs with the correct
piece of state and also to make it so
that i can't click all of my inputs the
way i can now i need to add a name
property to each one of these inputs
like we've done before i'll set the name
equal to employment which exactly
matches the property that we are saving
in state the reason we're giving the
same name to all three of these radio
buttons is first of all in html that's
the way that we make it so only one of
these radio buttons can be selected at
any given time but it also intuitively
makes sense because we're only updating
one property of employment based on
which one is selected each one of these
inputs will have its own unique value
and this value is what will actually get
saved as the value in state when this
specific input is selected
so for the unemployment or the
unemployed one i'll put unemployed
for part time we'll use part time
and for full time we'll use full time
next i need to make sure that i'm
listening for change events so i'll add
my on change of handle change believe it
or not we'll also be able to use the
same handle change function and we'll
see why in just a minute and technically
speaking this should now be hooked up
correctly to state i can test that by
coming up here and console logging my
state will just console log the
employment part of it so we'll say
console.log form data dot employment
i hit refresh we get an empty string and
then when i choose unemployed it
switches to unemployed
part time and full time there's one more
small thing that we need to change and
it's essentially mirroring what we did
when we were setting our value equal to
the state radio buttons are a little
different because we need to specify
what value the state should take on if
the radio button is selected or checked
however that means that we can't do
controlled components in the same way
that we did with our inputs by setting
the value equal to whatever the current
value of state is but that doesn't mean
we can't control these components it's
just that radio buttons are controlled
in the same way that checkboxes are
controlled here we were able to say
checked equals form data dot is friendly
however if we try to do the exact same
thing with our radio buttons we're going
to run into a little bug we'll see that
here i'll say check equals form data dot
employment
and when i click one of them well some
weird stuff is happening
this is where radio buttons differ from
check boxes in that when we are
controlling the checked property we
don't simply say checked equals form
data.employment because unlike a
checkbox this is not a boolean value but
we can make it a boolean value by
checking if the form data.employment is
equal to the value of this specific
checkbox so i'll do the exact same thing
over here
and now react is in charge of
controlling this input rather than the
input having its own html state let me
walk through that one more time let me
hit refresh
initially the value of
formdata.employment is an empty string
when i click unemployed it runs the on
change for handle change which we have
defined here
we're pulling the name value type and
checked out we're setting the form data
we're bringing in all the old form data
now we're using name which we had set to
employment as the key for our state that
we're updating and it looks here says is
the type checkbox
in reality no this is not a checkbox
it's a radio and so it skips the checked
value and instead uses this value this
value is the value that we defined here
where we said it's either unemployed
part-time or full-time
then when we change state react
re-renders our form it checks to see if
the current form data.employment is
equal to unemployed in our case since
that's the one we chose then that
becomes a true statement and therefore
checked is true and all of these other
checks are false
that makes it so that only one of these
can be checked at any given time
in my opinion radio buttons are probably
the most confusing element to deal with
in react so if you have understood
everything we just walked through then
kudos to you truly this is a big
accomplishment so you really should be
proud of yourself again you don't need
to have memorized this necessarily you
can always come back to this lesson or
find something on google to help you
through the syntax of this if you need
it again in the future but if you were
able to follow along with the logic that
we just talked through then that really
is a good signal that you understand
state you understand event handlers and
some of these little quirks about forms
in general there's one more form element
i want to talk about before we move on
and that is select boxes and we'll do
that in the next screencast
the last form element we're going to
talk about in react is the select box
with its options
in regular html it's usually set up
something like this where you have the
select box i've added an id just so we
can associate our label with it and it
has a number of options inside with a
value for each option
in regular html in order to grab the
value of whichever one is selected you
will look for a property called selected
although that would happen in the
javascript but all of this is a bit
beside the point because react has
decided to make it a lot more similar to
some of the other input elements that we
have seen so far so just like we've done
with some of the other elements we are
going to add a value property here on
the select itself and this value similar
to our text inputs we'll just mirror
what we have in state now currently
we're not saving a favorite color in
state so let's go ahead and add fave
color we'll start it off as an empty
string
and then down here in our select we will
say form data dot fave color
we can reuse the same on change handler
that we've been using with handle change
and in order for handle change to work
correctly we need to make sure that we
mirror our name to exactly equal the
property that we're saving in state
so at this point i should be able to
click my drop down and you won't see
this drop down in the recording but if
you click onto this app and hit the
refresh icon you can test this out for
yourself i'll click the drop down and i
see the different colors red orange
yellow green blue indigo and violet i
can choose green and that will change
our drop down to green and actually
let's go up here and change form data
employment to
console log our favorite color instead
so that way whenever i make a choice
like green
our state is updating according to the
value of the option that was chosen in
this drop-down box
now we do have one little issue here if
i hit refresh we see that i'm
initializing state as an empty string
for the favorite color but currently i
don't have an option that represents the
empty string value one way i can change
this is by providing a new option where
the value is an empty string and then
maybe i put in something like choose
that makes it so that the user will see
choose here on the first option
i'll hit refresh
we see choose as our option but i can
still drop this down and change it to
any of these other colors just like we
would expect
and that pretty much does it for any of
the form elements that we're going to be
talking about in this course there's one
last small thing we need to cover about
forms which is how to submit a form and
so that's what we'll cover in the next
lesson
now that we have a way to gather all of
this information from our user we need
to be able to submit the form
in html you might be familiar with an
input of type submit
an input type submit is well basically
just a button and of course the default
option there is submit we can change the
value to something different like
i don't know send it in or something
okay and that changes the text of the
button let me put a couple breaks here
just to move that down a bit
however in html5 they made it so that
the actual button element
if it's found inside of a form acts like
a submit button
what's nice about the button element
inside the form is that you're not doing
this weird value thing because it's not
really a value it's just the text of the
button so i could just put submit here
and because this button is found inside
of a form element its type is actually
automatically submit by default in fact
if you didn't want it to act like a
submit button you'd have to actually
change the type to button which looks
kind of funny button type button so
let's just make use of that default
we'll get rid of our type completely and
therefore the default is type submit and
clicking this button because the button
is found inside of a form will actually
trigger the forms on submit event
handler
now back in the day instead of having a
javascript on submit handler you might
have something like a method that tells
you this is going to be a post request
and you'd have an action that probably
led to some php file.php
and then php would take the data and
process it do whatever you needed to do
however we're going to essentially
bypass that entire system we're going to
set up the on submit event handler and
let's create a function called handle
submit
and up here i'll actually create that
function
and what's nice about the way we have
set up our form in react is now instead
of having to go through every one of our
inputs and gather the values right at
the last second before we submit this to
maybe an api we've been doing all that
work all along as we've been updating
state on every change of the inputs and
elements in our form
so if we pretended that we had some kind
of submit to api
function
we would really just be able to probably
pass our form data object into that
function because it's already updated
it's been updated after every change of
the form
now just like in vanilla javascript if
you have built a form and gathered the
data in javascript you know that
clicking this submit button will
actually refresh this page and it'll put
all of the form values as part of a
query string in the url that all harkens
back to the original way that forms were
submitted with an action property so the
first thing we will always want to do in
react when we're handling a form submit
is to take that event object that will
get passed to this event handler and run
event dot prevent default
preventing the default means that it
won't refresh our page and essentially
re-render our app with all of these
default values and state preventdefault
just stops all of that from happening
and makes it so that we can then run
code the way that we actually want to
just to see this working i don't
actually have a function called submit
to api so let's just console log
our form data so before we test this out
let me remove some of these console logs
so we can actually see what we're
working with i'll hit refresh type in
some generic values here
okay and we'll hit submit and we can see
we got our state object everything has
been automatically updating as we've
been typing things into our form and
maybe just to drive the point home let
me comment out this prevent default
and i'll type in some stuff here
and hit submit
you can see my form refreshed and then
my url actually updated i'm not sure if
that comes through in the recording but
this is the url and it took all of my
values based on the name properties
stuck it as query strings in the url and
it's just not what we want to do
okay with all of that behind us i do
want to get your hands on the keyboard
practicing some of the things we've
learned with forms so that will be what
we do in our upcoming challenge
okay we've covered a lot of ground so
before we move on i want to test your
skills and your knowledge make sure you
were paying attention so with this quiz
pause the screencast click into the
editor type down your answers and when
you've answered all the questions click
play and we'll go over the quiz together
number one in a vanilla javascript app
at what point in the form submission
process do you gather all of the data
from the filled out form
all of that data gathering happens right
when the form is submitted
i should say right before the form is
submitted usually you listen for the
form submit event and then you'll go to
each one of the elements in the form and
gather the data
so in number two it asks basically how
is that different in a react app well in
a react app we're basically not allowing
the form elements to maintain their own
internal state but instead the component
that houses the entire form has some
react state and that state is updated on
every change of the elements in our form
so for a text form it's every keystroke
that the user types into their keyboard
for a checkbox that's every time the
checkbox changes or the radio buttons
change and so forth so in short we
gather all the data as the form is being
filled out
and of course all that data is held in
local state
number three which attribute in the form
elements for example the value name on
change etc should match the property
name being held in state for that input
well it's the name property
essentially we use that name property to
help us in our on change so that we know
which property in state to update
whenever a change happens
number four oh that a should not be
there what's different about saving the
data from a checkbox element versus
other form elements
in all the other form elements we're
using the value property to know how we
should update our state but with a check
box we're looking specifically for the
checked property
okay and number five how do you watch
for a form submit and how can you
trigger a form submit
simply enough we can add an on submit
handler
on the form element
that's how we can watch for a form
submit and we will pass a function to
the on submit handler that will run
whenever the form is submitted so then
how do you trigger a form submit usually
that will happen with some sort of
button click
as a quick reminder in the markup if you
have a button element that's inside of a
form
it will automatically act as a submit
button for that form alternatively and
what kind of seems like the older way to
me is to use an input
type submit
but to me there's not really a benefit
to doing that
okay awesome job on this quiz hopefully
you were able to answer all these
questions
next we're going to put what we've
learned about forms into practice
in this challenge your job is to connect
our existing form to some local state
and update that state whenever the user
interacts with the form as we've been
doing i want you to make sure that you
only create a single handle change
function that can manage the state of
all four of these inputs the email
address password password confirmation
and the newsletter check box then when
the user clicks sign up you'll run
through some logic that makes sure that
the password and password confirmation
match each other and if they do you
should log successfully signed up to the
console and if they don't you should say
passwords do not match in the console
additionally when the form submission
happens i want you to check if the check
box for the newsletter was checked and
if so log thanks for signing up to our
newsletter to the console if not don't
console.log anything there was a lot of
syntax that we learned when we were
going through the different pieces of
the form so don't be afraid to open up
in another tab some of the previous
lessons that we've gone through as a
reference so pause the screencast and
work on this challenge
all right let's do this i'm going to
start with some state
i'll create
state called form data and set form data
using react.use state
that will begin as an object and i can
provide this object some default values
let's have an email property that's
empty
a password property that is empty
we'll call this password confirm
and let's say
we be joined newsletter
this one will be a boolean because
that's what checkboxes deal in is
booleans and so we'll default it as
false or maybe if we're good marketers
will defaulted as true
and then what we can do is
add these properties as a name field in
each one of our inputs
so we'll add name equals and then we'll
put exactly what those properties were
from up above
while i have all of these selected i'm
going to add an on change for every one
of them
that will point to a function that i'll
create called handle change
and then we'll also give a value
property
and i'm going to change this on our
check box because that should be checked
not value this way they can be
controlled elements or controlled inputs
and i will make sure that we're pointing
form data
dot and then we'll paste in the values
that we copied above let's fix our check
box so this should say it's checked if
form data dot joined newsletter is true
or not checked if it's false
and now let's go create our handle
change function
from the event i'm going to pull out the
name property value property type so
that we can check if it's a check box
that made the change and the checked
property we'll get all of those from
events.target
target represents the element that was
modified in the event
then i can run my set form data function
and i need to
access my previous form data so we'll
say preform data and this will be the
parameter to my callback function
and i'm going to use that little trick
where i can return an object by
surrounding it in parentheses that way i
can make use of the implicit return
without having to open the body of this
function and then use the return keyword
and so forth and so i'm returning an
object and that object should have all
of the properties of the
previous form data but then i want to
update the property based on the name
value that we pulled from the input that
is making this change
that's using this computed property
syntax and the value would normally just
be value if i didn't have this checkbox
here because all of my other inputs are
updating a value property on the input
itself however because i do have the
checkbox i'm going to check if the type
is
checkbox and if it is then i want to
set the checked property of that
checkbox that's what's going to either
be true or false based on whether the
user has checked the box or not if the
type is not a checkbox then we can just
use the value property to update our
state
let's do a quick check before we get to
the handle submit part of the challenge
i'm just going to console log my form
data
and
let's see if
updates happen well it's good to see
that my checkbox is automatically
checked because that means that it's
connected correctly to state
and our default was set to true
so if i uncheck it we get false that's
good email address
password
and confirm password
cool everything seems to be connected
the way i would expect
so we can get rid of this console log to
clean up our logs down there
at this point all that's really left is
some vanilla javascript logic that we
need to write inside of our handle
submit and hopefully when you are doing
this challenge you notice that i already
set up our on submit to run the handle
submit function and because our button
is inside of the form element it acts as
a submit button automatically so
clicking the sign up button will trigger
the submit event on the form and
therefore will run the handle submit
function and well i accidentally deleted
the event dot prevent default i don't
want to delete that i need that
otherwise submitting the form will
submit it as if it were submitting to an
old php or backend which would then take
all of these values and submit them as
query strings in the url and refresh the
page and everything essentially i just
don't want to do any of that so
event.preventdefault is always going to
be the first thing that you'll do at the
top of your handle submit function
and yeah like i mentioned we just have
some vanilla javascript logic to work
through so if the password and the
confirmation match each other we need to
log successfully signed up so i can just
say if
form data dot
password
is the exact same as form data dot
password confirm
then console.log
successfully signed up and in any other
instance we will console log
passwords oh this says to not match that
should say do not match passwords
do not match
and then separately we can process the
data for the
newsletter and if form data dot let's
see what was it called
joined newsletter
if that's a true value then we will
console log
thanks for signing up for our newsletter
okay let's give this a test i'll open my
console
put in an email address
password
confirmation that is matching
and we'll have the checkbox checked i'll
hit sign up
successfully signed up and thanks for
signing up for a newsletter let's say i
changed this password to something
different passwords do not match
and well you know what that leads me to
something that i didn't mention in the
challenge but probably would make sense
to do
if the passwords do not match i don't
want to make the person think that they
signed up for the newsletter so i think
i'll just put a return right here after
my passwords do not match so that this
if statement never gets run in case they
don't match
let's try this again we'll hit refresh
and we will make the passwords not match
hit sign up and we just get passwords do
not match okay
then if we do make the match
and we
uncheck
we get successfully signed up without
the thanks for signing up to our
newsletter awesome obviously we didn't
touch on every aspect of forms that
we've learned about but a form like this
is a lot more common for you to develop
than something that has every kind of
form input under the sun awesome work on
this little mini section on forms
believe it or not we're really rounding
the corner almost at the finish line for
this section we just have a few more
things to learn before we can really tie
together the remaining aspects of our
meme generator project and finally tie a
bow on that and call it complete so when
you're ready let's jump right in
now that we've learned how to save input
data from text fields into state let's
revisit our meme generator and get it to
an almost complete state
we created earlier the top text and
bottom text fields but they're not
hooked up to anything right now so your
task is to connect the inputs into state
so that every keystroke they update the
top text property and state and the
bottom text property and state
now i've done a little bit of css heavy
lifting for you and that's because i
really want to focus on the state part
of react right now
but in short i've added a wrapper around
our image so that the whole thing is
considered the meme i made that meme
position relative so that i could set
the h2s to be position absolute this
meme text is styling it to look kind of
like a classic meme text and the top and
bottom classes simply stick it at the
top or at the bottom of the container
element and as you can see down here
i've hard coded the top text and bottom
text but part two of your challenge is
to replace that hard-coded text with the
text that we are saving in state
pause the screencast and work on this
challenge
i think the first thing i'll do is add
the properties that i need to my inputs
so that i can be watching for changes
let's add a name property to each one
say name equals and then we'll have
this one is our
top text
and this one is our bottom text
next we'll add our value properties so
that these can be controlled components
and those will be meme dot
and then top text for the top one and
bottom text for the bottom one
and then we're going to need an onchange
event handler
we'll call it handle change
and then we'll create that function
i'm going to pull in the event so that i
can get the name and value properties
from our event so i'll just restructure
those now
and that's going to be from event.target
and then i will essentially be doing
exactly what i did with get meme image
here with set meme
i'll type it out for the practice we're
going to set the meme
and i do need access to the previous
version of the meme
i need to return an object which if i
want to do that as an implicit return i
need to wrap my object my curly braces
that represent an object in parentheses
so that it doesn't think i'm just trying
to open up the body of the function
and we'll copy over all the properties
of the previous meme
and we will change either the top text
or the bottom text property depending on
what name gets pulled in from the target
so i'll use that computed property name
and set its value to value
lastly i will update my hard-coded text
to look at our object values and state
so this will be meme dot top text
and meme
dot
bottom text
okay let's cross our fingers i'll hit
save
one does not
simply
walk
into
mordor
ain't that the truth now it's kind of
like playing roulette here if i click
get a new meme image it's probably not
going to work out so great but we'll see
that our text is staying on top and on
bottom and switching the meme image can
actually be kind of a fun exercise
because your text may or may not apply
to the new meme image very well awesome
work this is super exciting basically
our meme images sort of had an mvp a
minimum viable product to push this out
to our customers in reality we are still
importing our memes data from a
javascript file when what we really want
to do is get that from an api there's a
few more things we need to learn in
order to do that successfully and that
is what we're going to start talking
about in the next screencast
a very common thing you'll need to do in
react is interact with an api that lives
outside of your application usually what
you're doing is either requesting
information from an api or sometimes
submitting information to an api
whenever you're requesting information
from an api in react usually you want to
display or use that information somehow
so getting data from an api in react
consists of essentially two parts first
of all you need to get the data
and that would be using something like
fetch or another tool for getting data
like axios
the second step would be to then take
that data and save it to state
once it's saved in state your
application can interact with it it can
display it on the screen and all of the
other benefits that come with saving
something in state
so let's see some preliminary syntax as
to what that might look like and then as
a spoiler alert i'm going to show you
why this is broken to do it this way to
start us off let's do a fetch request to
the star wars api this is just a very
simple api that will get us some
information about star wars characters
and planets and movies and stuff like
that i'll go ahead and resolve the
promise that i get back from fetch it
will receive a response which will be
json i want to turn that into a
javascript object that i can use
and then with that data
we'll just console.log the data for now
okay awesome we have this object here
i'm not going to bother digging into
this object i'm just going to stringify
the entire thing so let me put that into
state
and you know what i'm actually using
data in a couple places let's maybe call
this star wars data
and set star wars data
and then instead of console logging we
will set star wars data with the data
that we get back and then i need to make
sure to update down here as well
let's hit refresh and see what we get
okay there's the data from my api
awesome everything seems to be working
swimmingly
however let me illuminate something
that's going on behind the scenes right
now i'm going to console.log component
rendered
every time the app component renders or
re-renders by react it will run this
console log so let me open my console
hit refresh
and look at this
we've got an infinite loop of component
rendering let me comment this out
and hit refresh
now i want you to pause and think for a
second why was this console log running
over and over and over again pause now
and see if you can come up with an
explanation for why it was doing that
the reason we were stuck in an infinite
loop is because this fetch lives on sort
of the top level of our component
because of that anytime the component
renders it's going to call fetch
and every time it calls fetch it's going
to set the star wars data which is
updating our state and therefore causing
react to re-render this component and
then it's running fetch again
setting the state re-rendering the
component calling fetch again setting
the state re-rendering the component i
think you get the idea in fact even
though we're not seeing that happening
with this console log commented out it's
still being re-rendered in the
background so i'm going to comment this
out so that it actually stops
re-rendering and in fact the only thing
we really need to comment out is where
it says set star wars data when we had a
console log here
i'll uncomment this component rendered
and open my console we'll see that we're
no longer in an infinite loop and that's
because we're not setting state causing
the component to re-render so this x is
a perfect springboard into the next
topic that we're going to learn about
and that is how to handle side effects
in react
so that is what we will tackle next
we're now embarking on a journey that
leads to oftentimes considered one of
the most confusing parts about react and
that is how to manage side effects to
really understand what i mean by side
effects let's take a look for a second
at what react's primary tasks are first
of all react is in charge of working
with the dom in the browser to render
some kind of user interface to the page
the react team has created a really
simple interface to allow us as
developers to accomplish this with jsx
and elements that look just like html
under the hood of course react is taking
that jsx and turning it into elements
that can be displayed on the page
another task which we have mostly been
learning about in this section is to
manage state for us and if you think
carefully about it it's managing that
state between the render cycles in other
words react can remember state values
from one render to the next so that's
another thing that react does and we are
allowed to hook into that state using
the use state hook and then naturally
its next task is sort of a combination
of these two it needs to keep the user
interface updated whenever state changes
there certainly are other tasks that
react is accomplishing but you can
probably boil the main three tasks down
to these three so then what is react not
able to handle on its own the major one
that we're going to be discussing is any
kind of side effects or i put outside
effects here all that really means is
anything that lives outside of react's
purview or reach so some examples of
this are local storage on your own
browser for example we can of course use
code to access local storage but react
has no real hand in interfacing with
local storage along that line any kind
of api or database interactions that
occur in our code we can write that code
to interact with apis but react is not
in charge of that code or rather react
has no way to know which apis we're
going to be reaching out to similarly
any kind of subscriptions you might have
if you include web sockets in your
application for example you have a chat
application that updates live and as it
turns out even if you have two different
pieces of internal state that you need
to sync together or have one of those
pieces of state react to a change in
another piece of state react can manage
the state of each one behind the scenes
but it's not really looking at any kind
of crossover between those two states so
in the end it boils down to basically
anything that react is not in charge of
can be considered a side effect or an
outside effect
so using this api interaction for an
example if we look at our code from
before i commented it out so that it
wouldn't keep infinitely rendering we
can see that react is essentially just
doing what it's told it's trying to put
something on the screen it's trying to
manage state and it's trying to keep
state and the screen in sync if state
ever changes it needs to re-render the
component as a side note if this were
receiving props and somehow those props
were also to change for example if those
props were a piece of state in a higher
up component that then changed this
component would also re-render
so with our code living here on the top
level of our component react really
doesn't have a way to stop us from
setting the state here causing the
re-render which would then set the state
again causing the re-render and so forth
in that infinite loop
so the react team gives us a really nice
hook called use effect in the
documentation this is called the effect
hook and i like to think of it as a tool
that react has given us developers to
use sort of like a blank canvas that
allows us to interact outside of the
react ecosystem which again mostly just
consists of state props and the user
interface that it puts on the page
and i like to think of use effect as
being a tool that allows us to
synchronize react state with those
outside systems like our local storage
or an api now before we jump in i've
included here a link to the
documentation if you click this slide
you will be sent to this page where you
can learn about using the effect hook
again think of it kind of like reading
the textbook before coming to class now
you don't have to scour every single
word in the documentation but i do want
you to take a look at it read through it
and then when you've got a cursory
understanding of the effect hook then
we'll jump into the next screencast as
you're reading through this
documentation you'll run into a line
that says if you're familiar with react
class lifecycle methods you can think of
the use effect hook as component did
mount componented update and component
will unmount combined
so if you are familiar with class
lifecycle methods i actually want to
implore you not to consider this tip if
you have no idea what i'm talking about
then that's totally fine you can forget
everything that i just said about class
cycle methods but if you are familiar
with class life cycle methods the modern
advice these days is not to try and
think of the use effect hook as a
combination of these life cycle methods
but rather to work on retraining your
approach to understanding side effects
and react i know that might be strange
for me to be contradicting the
documentation but i know that i'm backed
up because this is an article by dan
abramov who is one of the core
contributors to react and he writes this
giant blog post about understanding use
effect and essentially goes in depth
into how we should not be thinking of
use effect as a way to hook into life
cycle methods but rather as a way to
deal with side effects and react if you
really want a deep dive you can click
this slide to go to this page but if
you're learning react for the first time
you do not need to go this in depth into
use effect at this time so once you've
had a chance to skim through the react
documentation on the effect hook let's
jump in and start learning how to manage
side effects in react
let's begin refactoring our code here to
use the use effect hook just as we can
access the use state hook on top of the
react object we can do the same with use
effect so i can create a side effect by
using react dot use effect and use
effect has one required parameter and an
optional second parameter in this
screencast we're just going to learn
about that first required parameter and
in the next one we'll talk about the
optional second parameter the required
first parameter for react.use effect is
a function a callback function and maybe
so that's perfectly clear i'm going to
write this out as a function declaration
although in practice you'll almost
always see this as an arrow function and
that's what we'll eventually transition
to as well
and this function acts as a place for us
to be able to put our side effects code
in the little example we have here this
fetch request is considered a side
effect and that's because it's reaching
outside of react's ecosystem but also
trying to set some state in the process
remember this was infinitely looping
because on the top level of our
component it was running this fetch and
setting the star wars data which was
modifying state and therefore
re-rendering the app which then just ran
all the code again in this infinite loop
so let's move this fetch request inside
of our use effect and that's it inside
of the callback function that we provide
to use effect we're allowed to put our
code that has other side effects that
interact with systems outside of react
and maybe more specifically interact
with those outside systems to keep them
in sync with our local state in this
component now i do have a confession to
make we're actually only halfway there
if i uncomment my console log and hit
save you'll see that we're still having
the same problem we were having before
where we're stuck in an infinite loop
let me comment this line out so that it
doesn't keep setting state so what
exactly is going on i thought use effect
was going to fix this problem well it
turns out that the code we put inside of
this callback function if we don't
provide a second parameter to our
react.usefx function then there's almost
no difference between putting our code
inside of use effect and putting it
outside of use effect on the top level
of our component there is one small
difference and that is anything that we
put inside of this callback function is
guaranteed to run only after the user
interface has been painted to the screen
in other words only after react has
taken our user interface our elements
and created real elements on our page
so this callback function is guaranteed
to run in a specific order only after
this has been
placed on the dom but for our purposes
here there's basically no difference
we're still stuck in an infinite loop
so in the next screencast we're going to
start diving into use effect and
understanding first why we need to
provide the second parameter and then
what that second parameter is and how it
solves this problem
i've made a couple modifications to our
app here to try and demonstrate exactly
what's happening within use effect i
came up with the simplest little counter
app that just has a single button that
says add
and something that displays what the
current count is in state the reason i
did this was just to make it so that we
had a really easy way to trigger
re-renders and state changes on our app
here i also replaced our use effect
callback function with just a console
log that lets us know that this effect
function ran
you can already see what's happening
down in the console but if i refresh the
site we'll first get the component
rendered console log and then we get the
effect ran console log as we talked
about before the function we passed to
use effect will run after every render
of our component it essentially makes it
no different than moving our console log
outside onto the top level of our
function just like we have here
which means if we ever wanted to change
the state within our use effect we get
caught in that loop like we've talked
about a few times already now with my
little counter i can trigger a manual
re-render by just clicking the add
button and we can see that when i click
the add button it updates the state
behind the scenes so it changes from
zero to one and it re-renders our
component now with count equaling the
number one we get our console log which
rendered because it's a function call
here on the top level of our component
it then would have skipped down here and
rendered our ui so that it could display
the correct count now that count is set
to one and last of all it ran our effect
which of course runs after every render
as we talked about the first parameter
to use effect is this function but
there's a second parameter which
although i mentioned is optional is
something that you will almost always
include and that is something called a
dependencies array now don't let the
name confuse you the concept is actually
not too terribly difficult the array
that we pass as a second parameter to
use effect will contain values that if
they change from one render to the next
will cause this effect to run in other
words it limits the number of times that
this effect will run or rather it
determines when this effect will run
instead of running after every single
render
now if i leave this as an empty array it
effectively tells react i want to run
this function on the very first render
of my component but then there are no
dependencies to watch and trigger this
effect to run again so it ends up being
it runs once when the component first
loads and that's it never again we can
see this in action by refreshing our app
seeing that we did get effect ran and
then adding to our count
and from here adding to our account is
no longer running this effect and that's
because we have an empty array which is
not looking for any changes between one
render and the next now if i wanted to
run this effect every time count changed
i would have to make sure that my effect
knew
that count was one of the dependencies
that signaled to the effect to run again
so now i hit refresh it will run once
which is why we get effect ran in the
console and now every time i hit add i'm
also running my effect again
under the hood this is what's happening
when i hit refresh state starts out as
zero and the component will take count
and replace it with a zero everywhere it
can find it so here we have an array
with the number zero in the first index
or the zero index then when i click add
react will update the count from zero to
one and it will re-run my function or in
other words re-render my app component
where everywhere i'm using count is now
one
remember this used to say count well the
second time around it changed from zero
to one so now it's running this
component
with an array where one is the first
index or the zero index in that array
then it's going to look at the last time
it saw this dependencies array and it's
going to compare an array with the
number zero
to an array with the number one
now i probably shouldn't use triple
equals because that's not exactly what's
happening here let me say
okay compared to it's going to compare
this array to this array and if any item
in this array is different then it knows
to rerun this function
now here's the question what if i were
to hard code an array with the number 0
in here let me hit refresh we can see
that our effect did run but now what
will happen when i cause a re-render to
trigger if you need to you can pause and
think through that for just a second
well i can click add and we'll see that
my effect is not running again
why do you think that is
well with a hard-coded zero in here
every time the app re-renders and use
effect looks at my second parameter of
this array it's comparing the array with
the 0 as the first item in it to an
array with a 0 as the first item in it
it's going to see that those are exactly
the same values and therefore it will
not run this function
and that's why it's called a
dependencies array use effect depends on
these values to know whether or not it
should rerun our
effect so again when i put count i
refresh the page count starts at zero i
hit add count is one it notices that
that has changed and therefore it reruns
our effect i feel like i've repeated
myself a lot here but i'm hoping that
the concept will sink in the more times
you hear it okay it's high time that you
get your hands on the keyboard so let me
type out a quick challenge
okay it's your turn to write the use
effect the use effect should run anytime
the count value and state changes and
for now it's just going to console.log
something like effect function ran pause
now and work on this challenge
we can start our effect by using react
dot use effect as a side note just like
we could the structure use state from
the import statement up here we can also
restructure use effect if we wanted to
and just say use effect in fact i would
suppose this might be the more common
way that you'll see it but just like
with use state i'm going to use react
dot use effect just so that it's very
clear where use effect is coming from
use effects takes a function as its
first parameter before we had a function
declaration like this
however i am going to use an arrow
function because that is how you will
most commonly see it
this is just going to console.log
effect function ram
now here's something tricky without the
second parameter we know that this
function will run any time the app
component re-renders and right now the
only way we're causing re-renders is by
clicking the add button let me hit save
i can click the add button and we'll see
basically the same thing that we had
when we had a dependencies array however
as i mentioned there's almost never a
reason to not include your dependencies
array there certainly are instances
where it may be required but especially
on the beginning end of learning react
you almost always will need to include
your dependencies inside this array if
you have no dependencies remember that
means that your effect function will
only run once the very first time your
component is rendered however our
challenge specifies that it should run
anytime count changes so let's very
explicitly put count in here and now i
hit save anytime count changes we get
effect function ran in the next lesson
let's bring back our star wars data and
get that displaying on the screen again
but this time without an infinite loop
occurring in the background
it's quiz time again pause the
screencast read through the questions
type down your answers and when you're
ready hit play and we'll go through the
quiz together
what is a side effect in react and what
are some examples put very basically a
side effect is essentially any code you
want to run that react is not in charge
of handling a majority of the time you
can think of that as your code that will
have some kind of effect on an outside
system so some examples of that might be
local storage
anytime you interact with an api
something like web socket subscriptions
however another example of side effects
is whenever you have two pieces of state
two states that you want to keep in sync
with each other
so those are the examples maybe to
answer the first part of the question a
side effect is
any code that
affects an outside system
the two states keeping in sync maybe
doesn't fit perfectly in with that but
hopefully our examples clarify that a
bit so then what is not a side effect in
react basically anything
that react is in charge of
so some examples of that is maintaining
state between one render to the next
and keeping the
ui basically in sync or displaying
correctly with the data whatever that
data might be whether it's state or
props there's certainly other things
that react is doing but it mostly boils
down to these two or three things i
think we have in the slides about what
its primary tasks are so yeah to take
our elements and render them to the dom
as well so we'll say
render dom elements
okay number three when does react run
your use effect function and when does
it not run the effect function well it
will always run your effect as soon as
the component loads
so that's on the first render of your
component and then by default assuming
we don't pass any dependencies to our
dependencies array like we asked about
in question number four it will run our
effect on every re-render of the
component
so that's assuming no
dependencies array and when does it not
run the effect function well it will
only not run the effect function if
there is a dependencies array available
in which case it will not run the effect
will not run the effect
when the dependencies in the array
stay the same
between renders
and maybe i should say when the values
of the dependencies in the array stay
the same
between renders
okay that leads us in perfectly to
number four how would you explain the
dependencies array well syntactically
it's the second parameter to the use
effect function
and its purpose is to allow react a way
to determine whether it should rerun the
effect or not it ends up being an array
of values that when react is in charge
of re-rendering a component it will
compare the values in the original array
with the values in the new array that
the effect is running when the component
re-renders and if any of those values is
not the same it will rerun our effect
function
so on a high level it's simply a way for
react to know whether it should
rerun the effect function
okay awesome job on this quiz we're
really rounding the final corner on this
section we just have a few more things
to cover so when you're ready let's jump
right in
i want to work through together getting
our little app back to a state where it
can pull the star wars data without some
kind of infinite loop happening in the
background so i have a small series of
quiz questions i'm going to ask first of
all what will happen when i uncomment
this code and hit save how is my app
going to act with my use effect function
set up exactly this way make sure to
look very carefully through the code
here don't refresh the app or anything
like that just use what you have learned
so far about use effect and the
dependencies array to figure out exactly
what a use effect that looks like this
means
well for one we can see that we're
telling use effect that it depends on
the count variable which means that if
count ever changes it's going to run
this function again
and if we look closely in the function
we see that we're receiving the data but
we're just console logging it we're not
currently updating our state with that
data let's open the console and see if
this holds true to what we expect i'll
hit save
the very first time around it's console
logging the data that we got back from
the star wars api and then if i change
my account it's logging it again not
only is it logging it again it's
actually going out to the api and
getting the data a second time so that
leads me to the next question in our
quiz
the second question is how will this use
effect be different if i use set star
wars data
instead of the console log
like before i want you to pause and look
through this code try to analyze it and
see if you can understand how things
will be different now
the main difference of course is that we
are actually going to be updating our
state when we receive that data back
updating that state is going to trigger
a re-render of our entire component
however that re-render will not change
the value of count and therefore will
not change this array from one render to
the next
and therefore will not rerun our effect
so let's hit save
we'll see that our data populated it all
happened kind of quickly but really what
happened in the background is our
component rendered the first time which
ran our use effect if i haven't said it
explicitly use effect will always run on
the first render that triggered the
fetch request to go get our star wars
data which eventually set the star wars
data setting the star wars data updated
state which caused the component to
re-render again
so now star wars data is the object that
we see it rendered the star wars data as
a json object to our screen
and then the effect checked to see if
the old count still matched the new
count and sure enough it did and
therefore it did not rerun our effect
because it didn't rerun our effect we
did not get our star wars data again
which would have caused that infinite
loop
if i remove my dependencies array
completely then we're back where we
started we're setting the star wars data
re-renders the component which runs our
function which sets the star wars data
which re-renders our component and so
forth now it is pretty contrived to have
a dependencies array that is looking at
the count because if you thought all the
way through this you would also notice
that if i scroll down and i click my add
button it's going to make another call
out to the api we don't have a console
log or anything like that i bet if you
were to open your developer tools you
would have seen in the network tab that
it did make another request out to the
star wars api and it did set our data
here which would have caused a re-render
we just didn't notice anything because
the data that came back is exactly the
same as what we had on the screen before
so that leads me to the third quiz
question
what exactly should be in our
dependencies array in this case
we can see that our code is not making
use of count usually what you put in a
dependencies array will also show up
somewhere in the function but right now
we're not using count to determine how
this function runs at all so if count
shouldn't be in our dependencies array
what should be there
some of you might have thought that it
should be star wars data
but if we think through what we've
learned about the dependencies array
we'll know that if i put star wars data
in here and set star wars data inside
the body of that function i'm going to
get an infinite loop again because when
i set star wars data it's going to
change star wars data and it's going to
re-render the app which will then run
our effect and we'll end up in that same
loop
assuming i only want this api request to
happen when the app first loads if i
leave this empty because there are no
dependencies for this to run then i can
successfully set up my effect so that it
will just run the api request on the
very first render of our component now
we can see if i hit save
it updates our data and actually you
know what let me put a console log here
i'll say effect ran or hit save again
we get our data we get the log for
effect ran but now even updating my
account is not running our effect again
i know this has probably been a lot to
take in but i'm glad you've stuck with
me so far i really hope you thought
through those quiz questions as i gave
them to you if not you always have a
chance to go back and re-answer those
quiz questions and when you're ready in
the next screencast we're going to
extend this example just a little bit to
try and help drill in the way that use
effect is working
we're going to start right off with a
challenge i want you to combine our
count with our current url that we're
using to get our star wars character so
that clicking the get next character
button will do the fetch request but for
the next character id
right now it's the character of one
which as we can see is luke skywalker
and i've updated our state to begin with
one because i don't think that there's a
character with an id of zero so
essentially clicking get next character
will increment count but instead of
having a hard-coded one in here it
should look at whatever the current
count is to make this request while
you're at it don't forget to consider
your dependencies array pause the
screencast and see if you can get this
new feature to work
there should only be two small changes
that we need to make
one is instead of hard coding a one
there we can add to the end of the
string our current count now i prefer to
use the template strings if i can so i'm
going to change this to a template
string and then instead of using plus
count i will interpolate the count value
inside
now if i didn't make any changes to my
dependencies array think for a second
what's going to happen when i refresh
and i try to get the next character
when i refresh my component is going to
run and it will run this effect because
it will always run this effect on the
first render count will be set to one
and so it will make a fetch request to
the star wars api where the endpoint is
people slash one however because i have
nothing in my dependencies array nothing
is going to trigger this function again
let me put count back in here and i need
to make sure that i will rerun this
effect anytime count changes
so now i'll hit save
after the first render it went to the
api and got the character with the id of
one we can even see here it says the
count is one then i'll click get next
character
the count is two
and after a little bit we get our next
character the one with the id of two
which is c3po so when i click get next
character it updates count
updating count reruns my function or
rather re-renders my component the
effect then looks at the old array which
was an array with one item with the
number of two in it and then it looks at
the new array which is an array with the
number of three in it and notices that
something has changed which is then a
trigger to run my function again with
the new number of three as count we have
a couple more things to learn about use
effect before we can check that one off
our list but before we do that it's time
that we go back to our meme generator
and we use our new knowledge to apply
what we've learned about making an api
request and saving that data to state so
that's what we'll do next
all right we've made it to the very last
challenge of the meme generator and then
we'll have completed the project if you
remember up until now we've been
importing our memes data from a file
that i created and this data just came
literally copy and pasted from an api
request to the imageflip api but since
that's not usually how things work
instead we're going to make that api
request ourselves and we'll do that
inside of the meme component so your
challenge is as soon as the meme
component loads for the very first time
you should make an api call to this url
once that data comes in you can save the
memes array part of that data so the
data will look like this object and you
can save just the memes array part of
that data to our all memes state you
might notice i renamed this from all
meme images to just all memes and that's
because the meme data that comes in is
not just an image they are objects that
contain a url but i thought that all
meme images might be a little bit
misleading since you know that you'll
probably need to use use effect to
accomplish this api request you should
think carefully about what the
dependencies will be if any that if they
were to change you would want to cause
to re-run this function if there are any
dependencies make sure to include them
and if there aren't any then make sure
you understand why
as a hint if you have used async await
functions before or you feel really
comfortable with them for now don't use
them we're going to learn in the next
screencast how we can successfully use
async await inside of a use effect but
it turns out it's a little more
challenging than it might seem on its
face
so for now just use dot then blocks to
resolve the promises that come back from
making a fetch request alright the time
is yours pause the screencast and work
on this challenge
all right maybe right here below our
state i will make a call to
react.use effect the first parameter is
a function i'll use an arrow function
since that's a more common way you'll
see it and let me actually think about
the dependencies first now i want this
api request to happen as soon as the
component loads and if you remember what
we're doing is saving all of those memes
in our state and then we're accessing a
random one of those memes to determine
what image should get showed in here
however there's nothing that is changing
in state that will actually require me
to make another api request and so since
i have no dependencies for this effect
i'm just going to leave an empty array
then inside of our effect we will make a
fetch request to this url so i'll call
fetch
put in that url
resolve it with the dot then we're going
to take the response and parse the json
into javascript
and then we'll have some data back
and before we jump into setting state
let's just console.log that data and see
how we're doing
we'll hit save and awesome okay that
looks very similar to what we have in
our memestata.js file so now we should
be able to use set all memes instead of
console.log so we'll put in set all
memes however if you read carefully it
says that we just want the array part of
the data that we get back so i'm not
going to put the data in there if this
object represents data then i actually
have data dot data maybe data wasn't the
greatest choice because we have
data.data
that's an object that has a memes
property so data.data
so let's put that in here
data.data.memes
outside of my effect i think i will just
try console.logging
all memes
and so what should happen is on the very
first render we have no dependencies so
this effect will not run again but on
the very first render it will fetch our
memes obviously parse the json and then
set all of our memes to the data data
memes array
setting our state will cause a re-render
which should then run our console log a
second time this console log will run
the first time that it gets rendered and
then again after the state changes now
of course if i left this here it would
also console log all memes for every
character that i typed into my inputs or
every time i click the button but for
now let's just see what this gives us
ah and that was confusing to me because
we are initializing it with memes data
let me actually delete memes data and
then put in an empty array here the
empty array is i'd like to think of it
as an empty box that we will then fill
with our memes as soon as our component
loads the first time
let me hit refresh again
okay and that time we got an empty array
first from our first time this console
logged and then we got the array of
memes from the api
awesome so i can delete my console log
actually let's see
now every time i type something here
we're going to be logging the all memes
array to the console so we don't want
that
let's go ahead and make sure everything
else is working correctly
we'll click get a new meme image
ah and we actually have a bug in our
code i think i'll actually make this a
challenge for you
okay your challenge is to try and figure
out why our code is broken as a hint it
does have to do with the difference
between what we were importing before
from our memestata.js file and how we
were using that versus what we're
setting as our state in set all memes
inside of our use effect pause now and
see if you can fix the bug that we've
introduced
as we saw before when we were importing
the memes data we were receiving this
object so we had this object which we
called memesdata.data.memes
however in state when we were setting
state we were initializing it with the
entire object not just the memes array
so we kind of switched things up when we
were setting the array in state instead
of the whole object however down in our
get meme image we were accessing the
memes array by using all
memes.data.memes but now all memes is an
array it's not an object with a data
property
so i think i can actually just get rid
of this line completely and replace
memes array with all memes
and i won't need this line anymore
so now i'm accessing all memes.length
and i'm indexing into all memes at our
random number to receive the random name
image
so let's try again we'll hit save
one does not simply walk into mordor
get a new meme image
very nice
just to polish things off i'm going to
clean up this challenge i'm going to
delete our memes data file
and awesome everything is looking great
before we can tie off a nice little bow
on this section i want to talk about use
effect for just a little bit longer as i
mentioned if you're familiar with async
await it may have been tempting to say
well i want this callback function to be
an async function so that i can use the
await keyword here
and use a little bit more tidy version
of our promises here so that would look
something
like this where you say the response is
wait for the fetch to come back and then
you would say data is await
response.json
and then you just set
all memes to be data.data.memes
if you're familiar with async await
obviously we can see this is tidier and
this would be really nice to use however
you'll never want to make this function
an async function and to really
understand why we need to talk about one
more thing that we can do with this
function inside of our use effect so
before we move on let me undo that
and let's talk more about that in the
next lesson
we'll start this one off with a pretty
simple challenge just to make sure
you're still awake in keeping your hands
on the keyboard in our app component we
are rendering a button and a component
called window tracker and over in window
tracker right now all it's doing is
displaying the current inner width of
our window because it's directly
accessing the window.enter width as soon
as the component loads that's not
updating but we're going to get to that
later
so if i hit refresh it'll give me a new
window width but we're eventually going
to make it so i can change the window
width and that number will dynamically
update however for now let's focus on
this challenge your challenge is to
create some state called show which we
will default to true make it so that
when the button gets clicked it will
toggle that show value back and forth
and conditionally render window tracker
only if show is true pause now and work
on this challenge
okay let's create some state const
show
set show
equals react. use state with the default
of true
i'll create a function
just called toggle
that will run set show
it'll look at the previous version of
show and return the opposite of that
then we'll set that up as an on click on
this button
and last of all we will conditionally
render the window tracker component if
show is true so i'll say show and
the window tracker component easy enough
we'll refresh
and it's toggling on and off awesome now
here's something to take a look at if i
widen my window a little bit and then
toggle this off and back on you'll see
that our window width changed and that's
because when this component window
tracker gets toggled off it essentially
is what's called unmounted is completely
removed from the dom when i click it
back on it's remounted and therefore it
will re-run this window.inner width
which gives me the updated version of
window width the truth is though we can
do better than this what we can do is
add an event listener to our window that
listens for the resize event and then
whenever the window is resized we can
set some local states to our window
tracker so that we can display the
correct window width at any given width
without having to toggle it on and off
or refresh our page completely however
because it's an event on the window i
can't simply add something like an on
resize event like we have with other
event listeners up until now and so i'm
going to have to do a little bit of
manual imperative dom manipulation and
because i'm going to be interacting with
a system outside of our window tracker
component in other words the window
itself think for a second what tool does
react give us to interact with some kind
of outside system and keep our local
state in sync with it
that's right it's use effect so i'm
going to set up an effect we'll say
react.use
effect
and i'll put my callback function in
here and when we think about our
dependencies at first glance it could be
really tempting to say well i want to
rerun this effect if window dot
inner width ever changes
however something to keep in mind is
that this function our component
function gets run each time the
component is rendered right now when the
component is rendered window.inner width
is equal to 474
and that's a constant value that's not
going to change on its own
so let's say for example i refresh this
i change the window size just a little
bit
there has been nothing to trigger a
re-render of my window tracker component
because window.enter width is not
something that automatically re-renders
a component in react so that was a bit
of an aside but i'm going to remove that
and instead we're going to listen for a
resize event on our window so i'm going
to say window.add event listener
listen for the resize event
and then we will run the following
function
for now let's just console.log
resized
okay now i resize and we get our consol
log running awesome the next step is
something i think you can do pretty
easily by now and so i will type that
out as a challenge
your challenge is to create some state
we'll call it window width which you can
default to the current window.inner
width whenever the component is rendered
then inside of our event listener you
should update the window width every
time it changes and you should change
our h1 to not display the window.inner
width that it calculated the first time
the component rendered but instead to
point to our new window width state
variable pause now and work on this
challenge
okay we will create
window width and set window width
react.use state and we'll default it to
the current window dot inner width
that it calculates when the component
first renders
then inside of our callback function
instead of console logging resized we
will set the window width
to be the window dot inner width at the
time that this function runs
and last of all we will look at the
window width instead of window.inner
width
so now when i make changes here okay our
window width is updating dynamically
awesome
well now let's take a look at a little
bug that we have i'll clean up this
challenge first
remember our window tracker component is
only mounting when its parent is
allowing it to render with this show
variable
when it rendered the window tracker it
immediately launched or created an event
listener anytime the resize event
happens that event listener is
registered with the dom itself so even
if i toggle off my component and then
try to resize the window we see that we
get this warning and it tells us we
can't update react state on an unmounted
component so in the end what happened is
our window tracker is no longer a part
of the dom but the browser itself is
still listening for the resize event and
trying to set the window width of an
unmounted component this is something
called a memory leak and for now it's
good enough to know that you don't want
a memory leak now due to the challenges
that you just completed this screencast
is getting a bit long so in the next
lesson let's address this issue of the
memory leak and see what we can do to
fix it
previously we saw that if i were to turn
off my window tracker component or
rather stop it from rendering and then
run my resize event we get this warning
that talks about a memory leak as a
reminder it's because we set up an event
listener on the window which registered
it with our browser
and even removing the window tracker
component by toggling it off does not
automatically remove that event listener
one thing you should always try to be
aware of when you are interfacing with
side effects using use effect is any
potential consequences that might happen
if you don't clean up the things that
you do in that side effect this is just
one example where we're adding an event
listener that is not getting cleaned up
when this component unmounts but there
certainly are other instances of this
let's say for example you are creating a
websocket connection with maybe a chat
api and you have a little chat app that
will update your screen automatically
every time there's a new chat message on
the server well when you create that
subscription to the chat api and then
try to unmount the component it's always
a good idea to then sever that websocket
connection as a way to so to speak clean
up the effect that you have created in
your use effect and in fact that's
actually what we're about to learn is
called it's called the use effect
cleanup fortunately it's pretty easy to
do remember we have a function as our
first parameter to use effect but
currently we're not actually returning
anything from that function well as it
turns out what we can return from use
effect can be a function and you can
think of this as a cleanup function
in fact to make that more obvious let me
put this as a function declaration
so when react runs our use effect
function here it will receive in return
another function that it can use to then
clean up any side effects that you might
have created in reality it has no idea
what the side effects are that we
created so what we put in the body of
our cleanup function should be something
that well we write to clean up our own
side effects in the case of adding an
event listener there's a sister method
called remove event listener now with
remove event listener we need to pass
the exact same function that we provided
when we added it and so i actually need
to move this outside of the event
listener and set it up let's call this
watch width
then i can pass in the name of watch
width when i'm adding my event listener
but this allows me to then say
window dot remove event listener
the
resize event
and the event listener function i want
you to remove is this watch with
function
okay let's see that this is working
first i'll put a console log that says
setting up inside of my watch with event
listener and then inside of my cleanup
function i'll console.log cleaning up
i'll hit save let's resize the window
look at our console okay it's running
setting up every time the watch with
function runs maybe setting up isn't the
right way to phrase that since we're
actually running this every time the
resize event happens but that's that's
okay for now so we get a bunch of
setting ups and now let me toggle off
the window tracker actually let me
refresh and then do one little resize
and then i'll toggle the window tracker
and we see that we get the cleaning up
function that ran and now if i resize my
browser i don't get that memory leak
warning like i had before
so let's take a step back and walk
through this logically to understand
exactly what's going on here because
this can be a confusing topic
our app component is deciding when the
window tracker component should be
rendered as soon as we toggle that on
and it renders it to the screen
it sets the window width state it
determines what that should be based on
the current window width at the instant
that this component gets rendered
remember use effect will only run after
the dom has been painted or in other
words once the h1 has been rendered to
the screen so after creating the state
it will render our h1 and then it will
register our use effect
this use effect has no dependencies
because there's nothing inside of here
that's going to make me re-register a
new event listener and so it registers
this event listener on the resize event
of the window and then anytime i resize
it's reacting to the event listener that
i set up and then when i toggle off the
window tracker react recognizes that
this component has reached the end of
its life cycle and it's about to be
removed from the dom and so it takes the
function that it received from us when
it first set up our use effect and it
just runs it in fact it runs it kind of
blindly it doesn't know what that
function contains but we as the
developers are expected to successfully
clean up after our side effects and so
we remove that event listener and it is
gone
so one last recap use effect takes two
parameters the first one is the effect
that you want to run
the second one is any dependencies that
react should watch for changes in to
rerun your effect function and that
effect function is allowed to return
another function that can clean up after
any side effects that might be lingering
in case your component dies
now for many effects that you set up you
might find yourself not actually needing
to provide a cleanup function at all in
which case that's completely okay this
is not a required part of use effect for
it to work
as always feel free to play around with
this code i know that this can be a
confusing topic so the more time you
spend in it actually playing with the
code yourself the better off you'll be
understanding this return function does
bring us back to the topic that we were
talking about a few screencasts ago on
how we can't use this as an async
function and so let's go back revisit
that topic and then we'll finally be
ready to recap this entire section
i mentioned in a previous screencast
that we wouldn't be able to simply put
async in front of our callback function
for use effect and now that we've
learned about how we can return a
function from use effect to act as a
cleanup function we will probably see
why we're not able to put async in front
of this callback function if you're
familiar with async functions you know
that by putting async in front of your
function definition it alters the way
that function well functions in
javascript whatever i return from an
async function does not become a bare
value return that we can receive in a
variable when we're calling this
function but instead an async function
will automatically and always return a
promise
as i'm writing my async function
whatever i say should be returned is
actually what will be resolved as the
successful promise completion of my
async function
however since react is expecting the
return value from my async function to
be another function that it can use to
clean up any side effects that i create
in the process of running my effect if
what it receives instead is a promise
it's not going to be able to run our
cleanup the way that we want it to
fortunately for us there's a really easy
work around to this and that is to
define a separate function inside of use
effect and remember if you're okay using
got then syntax with promises then you
don't have to do any of this at all but
let's say you really are anxious to use
an async function well i can just call a
new function we'll call it an async
function
and maybe let's say get memes
and now because it's an async function i
can move this content in here and say
something like const response equals
await the fetch request
const data equals await res.json
and then with that data i can set my
memes now this is just a function
definition so the very last thing i need
to do before i'm done is to call my own
function here inside of this callback
function this is a lot of functions to
be dealing with for sure we've got a
callback function which has a function
definition a function call and then a
returned function but again if this is
too much then you can just go back to
using.then syntax with your promises and
that's completely okay as well
in our case with our effect we probably
don't need a cleanup function here
because we're just making this one call
one time it's happening as soon as this
component loads there isn't really a
built-in way for us to unmount the meme
component or anything like that and so
we can just delete our use effect
cleanup function that we were returning
from our callback function
i tried to take everything that we just
talked about and boil it down to a
written summary so if you're interested
you can read through the summary that we
just put here
and now we'll take the opportunity to
take a look back at all the new things
that we learned about react in this
section and we've covered a lot of
ground so when you're ready let's take a
look at all the cool new things that you
are now able to do as a react developer
holy cow i can't believe we are finally
here at the end of section 3. we have
covered an insane amount of topics and
you have built your first interactive
react app i mean even try to think back
to section 2 and what we knew then
versus what we know now it's crazy
before we wrap up the section let's do a
quick recap of everything that we've
learned one of the key components of an
interactive web app is the ability to
listen for events so we learned how to
add event listeners in our react app and
that was a crucial springboard for us to
learn state then even though we had seen
a sneak peek of conditional rendering
beforehand we officially learned
conditional rendering and saw a few
different ways that we can implement it
in our code
then we kind of waded through one of the
heavier topics of forms in react for
better or worse you'll end up using
forms pretty regularly in react and on a
side note i hope you mostly just have to
do input boxes instead of worrying about
all those other kinds of types but it's
important that we learn them so that we
can apply them when we need
and then we dove deep into understanding
side effects and how we can handle side
effects in our react code these topics
combined with everything that we learned
in the previous two sections make up a
really robust introduction to the react
library and of course there's a ton more
that you can still learn about react but
these foundational pieces give you the
tools that you need to build your own
basic web apps especially considering
the depth of the topics that we learned
in this section you should definitely go
over to the today i did channel in the
scrimba community discord server and
post a celebratory message saying that
you finally finished section 3 of the
introduction to react course in fact if
you click this screenshot it'll take you
right there and the end of this section
essentially marks the completion of the
topics that we'll be learning in this
course however if you know me at all you
know that i'm not going to let you go
before i get you to practice this a lot
of times so the next section is
completely dedicated to practicing
everything that we've learned and along
the way there's a couple new things that
i'll introduce here and there i'm really
excited to jump into the next practice
section and i think you should be too
we're going to be working on some really
cool projects before that though you
should bask in the glory of having
completed this section so once you're
all done basking i will see you in the
next section
if you're jumping into this section
because you have completed all of the
other sections all the exercises or
challenges and all the projects that i
have thrown your way then
congratulations you have done a lot of
work to really learn and hopefully
deeply understand react
naturally there's a million more things
you could learn about react it's a
framework you can dive really deep into
and get very complex with but at this
point you really have all of the
fundamental tools you need to build
highly interactive web applications on
your own
so at this point this section is
dedicated completely to you guessed it
practice
i know i've said it a million times
before i hope you're not terribly sick
of me saying it but you will not get
good at anything unless you practice it
over and over we know this intuitively
when it comes to something like learning
a new instrument or learning a new
language and is absolutely no different
when it comes to web development
so for the remainder of this section we
will be working on three projects and i
want to take a second and give you a
preview into what those projects are
now this will be a little bit different
than what we've done in the past so far
we've mostly been creating something
completely from scratch however the
first two projects i'm going to have you
work on you'll actually be jumping into
an existing code base and we're going to
ramp up to this a little bit the first
task you'll have is to revisit our react
fax site from the very first section in
this course but now to apply the
knowledge you have about state in react
to implement a light mode and dark mode
toggle which will allow the user to
toggle between those two color schemes
this one will end up being more of a
warm-up project because it will only be
one screencast long then you're going to
jump into a new project which is sort of
a markdown version of an apple notes
clone
some of the basic code for this will
already be written for you but some of
it will be broken and along the way
you'll also be learning something new as
you implement a new feature that
interfaces with local storage so you can
save these notes in a little bit more
permanent way
then for the third project we'll go back
to our roots we'll be creating it
completely from scratch and that is this
dice game called tenzi's
every single step along the way with
these projects is going to be a
challenge for you to complete so you
will get your hands on the keyboard and
you'll get lots of awesome practice to
help you really solidify the things that
we've been learning about react
so what are we waiting for let's jump
right in
we're going to start off with a sort of
warm-up challenge here usually when you
join a team as a web developer you
probably aren't going to be creating
your projects completely from scratch
but instead will sort of be tossed into
a new code base that you then have to
spend some time becoming familiar with
before you can do any kind of work on it
now the code base here fortunately is
something that you have worked on in the
past and that's the react facts site
that we worked on in the first section
but i'd like you to imagine that when
you finished the first version of this
code you handed it off to a team and in
the meantime they've been working on
implementing this light mode and dark
mode toggle but are needing some help
for you to add the functionality to it
so a major part of this challenge is to
spend a really good amount of time
looking through the existing code
because it has changed since you last
looked at it and make sure that you
spend some time understanding how
everything is working
in my little advice section here you see
it says to first start with index.js
work your way to app.js go to main.js
and navbar.js and then to follow the css
class names in the style.css so that you
can understand how things are working
while you're at it make sure that you're
looking closely at the conditional class
names in the jsx to help you decide what
props need to be passed down to the
components that need them
you should also think carefully about
which components will need state this is
going to help you decide where you're
going to write the code that initializes
the state and how to then pass it down
to the components that need to access it
in the slide down here i included a
couple screenshots that have both the
light mode and the dark mode you can
click on either one of these to go to
the figma file that has the specific
colors and other design aspects however
in reality the design has already been
implemented you shouldn't need to do too
much in changing the design because it
all is existing in the css on this next
slide i also have a little animated gif
that shows you exactly what should be
happening of course you click the light
and dark mode up top and that will
change every aspect of the site to its
light mode or dark mode color scheme
again jumping into an existing code base
like this is going to be a really common
task as a developer so when you're
working on part one of my advice here
spend a real significant amount of time
doing this i imagine it will
realistically take you at the very least
about five minutes but even upwards of
20 or 30 minutes before you maybe get a
good grasp on the code that we have here
okay the time is yours pause the
screencast and work on adding this light
and dark mode feature
let's start off by looking in index.js i
think we're going to find it's not that
impressive here we're really just
importing app and rendering it so let's
follow that down and go to app.js
looks like it is rendering a div with a
container class name that is containing
the navbar and the main elements which
we're importing up above so let's go to
navbar
okay this one's a little more
significant like i mentioned looking at
the conditional class names is going to
give us some good hints as to what we
need to do here we can see that navbar
is expecting props and specifically one
of the props called dark mode i'm
assuming this is a boolean because of
the way it's positioned in this ternary
here it says if props.dark mode is true
then apply the class name of dark
otherwise don't apply a class name at
all and if we look really closely we
also are expecting a prop called toggle
dark mode which makes sense because our
toggle here exists inside of the nav bar
so clicking this toggle should change
the dark mode from true to false or
false to true
the other thing app.js was rendering is
this main so let's go look at the main
it looks like main is also expecting
props
again props.dark mode so it's going to
do essentially the same thing and i
think that's it this one is not
expecting to toggle the dark mode
anywhere so we should be set up now to
create the state we need to make this
light and dark mode work
now because both the main and the navbar
are expecting an incoming prop called
dark mode that means that the parent of
those this app component that contains
or renders the navbar and the main
should probably be where the state is
being held so let's go ahead and create
our dark mode and set dark mode
which is react dot use state
maybe since the code right now is
showing that it is not in dark mode
let's set this to true
so that when everything is hooked up
correctly we'll see the page update i'll
pass the
dark mode prop
to both of my components since we saw
that they both are expecting it to come
in
and then the navbar specifically is
expecting something called i think it
was well let's just go look at it navbar
toggle dark mode so i'll copy that
that's the name of my incoming prop
and now i need to provide a function
which will change the dark mode i could
do that in line or my preference is to
create a separate function so we'll say
toggle dark mode
and that's simply going to call set dark
mode
looking at the previous mode
and it'll just return the opposite since
it's a boolean
and now let's pass our actual toggle
dark mode function down to the nav bar
i'll create some space here
let's hit save and when we do that it
should switch to dark mode
awesome okay and then we can click our
toggle great this is working just like
we'd expect
obviously what we have worked on here
might be a bit contrived because in our
case somebody already implemented some
of the major features that make this
work but that's what makes this a warm
up we're really gearing up to work on
something that's a little more in-depth
and the main takeaway i want for you in
this challenge is not so much
implementing the actual feature in this
case but instead taking the time
required to look through the code and to
understand the code of course if you're
working on this with a team you'll
probably have access to the developers
that had written this code and that's
when you could ask them questions why
did you write something the way that you
wrote it and that way you can get some
good insight from them on how it's
written and how you should proceed when
you're adding new features
okay i feel like we're nice and warmed
up so now we're ready to jump into
another existing code base which is one
of our major capstone projects for this
section
as a developer it can be really fun to
start new projects from scratch
especially when that project is one of
your own ideas however a much more
common task as a developer is to be
thrown into a code base that you're
unfamiliar with and asked either to fix
bugs or add new features naturally
before you're able to be productive on
any code that's new to you you need to
be able to read through the code that
exists to get a sort of lay of the land
and make sense of what you're seeing
only then can you start to feel
confident enough in the code base that
you'll be able to add new features or
fix bugs without actually causing new
bugs in the code or breaking an existing
feature now in reality this is where
something like automated testing comes
in really handy but unfortunately you
won't always have the luxury of working
on a code base that has robust testing
already set up for you and so i'd like
to introduce you to the markdown notes
app i guess i didn't get very creative
with the title this app already has some
bones set up for you you can see that
there's a list of notes that will be on
the left you can create new notes like i
just did with this plus button and on
the right there's a markdown editor
where you can toggle between preview and
right now this editor is not something
that i wrote this is built by another
team that made a package called react
dash mde markdown editor and we've
simply implemented that package into our
code here so on each one of these notes
i can type
new things into the note i can switch
back and forth between preview and write
mode everything here is markdown so when
i bold something it will surround it
with the double asterisks but when i go
into preview mode it will render that as
html and so we see a bolded paragraph
if you haven't spent much time doing
markdown you can play with the editor
here and get a general sense of how
markdown works toggle back and forth
between write and preview but as it
stands this notes app has some very
limited features first of all we see
that it's just calling our notes note 1
note 2 note 3 note 4. we also have no
way to delete any notes and probably
worst of all if i refresh this app all
my notes disappear this is the screen i
set up if we have no notes and we can
click the button to create one
so before we even dive in to look at
what features we plan on adding to this
project i have your very first challenge
which is to understand the code base
i'll type it out to be more specific
your first challenge is to spend a good
10 or 20 or maybe even more minutes
reading through the code and trying to
understand how it's currently working
now i say 10 to 20 minutes as a
guideline but you really should spend as
much time as you need to feel pretty
confident that you understand this
existing code although in reality you
don't need to fully understand
everything you see here just to move on
i will walk you through a high level
overview of the app but i really urge
you to actually pause spend this time
reading through the code see if you can
understand it before i get to my
explanation of it this kind of exercise
is crucial when it comes time for you to
actually jump into a real company's code
base so now is not the time to shrug
this kind of exercise off so pause now
and spend some time to gain an
understanding of this code
i think it never hurts to just start
right at index.js
although we can see here that well we're
really not doing anything we're just
rendering the app component but it's
good to know that we're not missing out
on something important here then i'll go
to app.js and we can see this is where
the bulk of our logic is happening we
have quite a few imports these top ones
because the path is starting with a dot
slash indicates that it's one of our own
components here we've got the sidebar
and the editor if i had to guess i would
probably say that this section on the
left is the sidebar and this whole
section on the right is the editor if
you looked closely you might have seen
data and gone over to data to see that
well we have some really basic seed data
or rather it's data that could be used
to create some initial notes for us for
testing purposes although it looks in
our case like this is not really being
used right now
back in app.js we can see we're also
importing something called split from
react split if you really went above and
beyond you might have actually done a
google search for react dash split to
see what it's doing and it turns out
it's a third party library that we
installed as one of our dependencies
right here and it allows us to have this
split pane that is easily resized by the
user so that's pretty cool we're also
importing nano id which you may or may
not have seen already and it looks like
we're using it right here when we're
creating a new note hopefully this also
illustrates the importance of naming
your functions and variables with a
meaningful name when my function is
called create new note it becomes really
obvious what this function is supposed
to do so then we come down to our actual
app component and it looks like we're
saving all of our notes in state
initializing as an empty array and then
we're creating this state called current
note id
and it looks like it's initializing it
either as the id of the very first note
or an empty string now you may have seen
this first part and been a little bit
confused honestly that's okay but as a
side note this is one way to essentially
say i need to make sure that notes at
the index of 0 because notes is an array
exists before i try to access the id
property of that note when we initialize
state as an empty array in other words
when i refresh this app and i have no
notes notes at the index of 0 is
undefined and trying to say undefined
dot id will actually throw an error in
javascript again that wasn't totally
necessary for you to fully understand
but that is an error you're going to run
into quite a bit
in more updated versions of javascript
there are different ways around this but
that's outside the scope of this course
right now
next we've got this create new note
function which is relatively
self-explanatory based on this set notes
call it looks like it adds the new note
to the beginning of the list and then it
looks like it sets the current note id
based on this note's id
at this point i might not totally
understand what the purpose of set
current note id is but that's okay this
update note looks like it is a way for
us to save and state any changes to our
notes that we create which allows me to
actually
type something here
and have that be saved at least locally
in state for now find current note well
this isn't setting state or anything so
that doesn't seem immediately obvious
what it's doing but if we look a little
further down we can see that it might be
a helper function that is helping us
determine what the current note is and
we're doing it both in the sidebar
component and the editor component to
pass the current note down as props to
that component again if i were looking
through this code base for the first
time and i saw this split component i
would probably end up going to the react
split documentation to try and better
understand how that works looks like we
are conditionally rendering this split
component if the notes array is greater
than zero in length but otherwise we
have this section here which is what we
get when we first refresh the app and we
have our title and our button
so that's a good enough start in here
let's go look at our sidebar
immediately i see this
props.notes.map which looks like it's
taking the array of notes and mapping it
into some note elements which are then
being displayed down here this will show
up better when i actually create a note
and if i create more notes it looks like
we have this class that actually changes
the sidebar style when one of these
notes is selected that's this selected
note dynamically rendered class name it
also looks like when we click anywhere
inside of a div we can set the current
note id which i presume is what's
helping us change this class and also
should be changing what actual text is
being shown here if i call this note 1
note 2
note 3 and then toggle between them yep
that seems to be saving or rather
correctly displaying the text that gets
shown up in our editor
then in our editor itself this one seems
fairly straightforward it is maintaining
its own state and it says selected tab
although the default here is right and
so i'm guessing that has more to do with
this little tab up here write or preview
and if you did take the time to go
search for react mde you might have seen
that this react mde component it takes a
prop called selected tab and on tab
change and that is something that's
built into react mde now something like
this which is creating this converter
object and has something called
showdown.converter
i assume unless you have done some kind
of markdown to html conversion before
this is probably completely foreign to
you something like this is probably not
super imperative for you to fully
understand in order to understand the
rest of the code base however it
certainly wouldn't hurt to go to
showdown and look at the documentation
to see if you can at least gain a
general understanding of what it's
trying to do
okay now i know that was pretty
long-winded but the truth is i'm really
hoping that you spent even more time
than that trying to understand
everything here fortunately in this
environment you also could have just
started clicking in here and making
changes to see what kinds of things you
could break curiosity like that is going
to be really helpful for you when you're
trying to understand how something works
now since this screencast is getting a
bit long i want to in the next
screencast start talking about the
features that we want to add to this
note-taking app
let's take just a minute to look at the
features that we will be adding to our
markdown notes app so that it's at least
a marginally usable app the first thing
we're going to do is sync all of the
changes that happen to our notes with
local storage we won't be saving
anything to a database in this project
but at least so that we have a way to
save our notes between refreshes of the
app we're going to be using the
browser's local storage to save every
little change that happens to those
notes next we're going to fix the thing
that's just showing note 1 note 2 note 3
because well that's not very helpful in
terms of trying to find our notes going
forward essentially create a note
summary and use that as the title in
reality it's just going to take the
first line of our note and put that in
our summary title right there
next we're going to add a feature where
every time we modify a note it bumps it
to the top of our list that way we have
our most relevant notes living near the
top of our list instead of possibly
buried way deep down on the list and
then last but certainly not least we're
going to add the ability to delete notes
along the way of adding these features
we are going to learn another thing or
two about react so that's going to be
exciting so assuming you've taken the
time to really dive deep into the code
and understand how this project is
working currently that means you're
ready to jump in and start working on
this first feature which we will be
working on in the next screencast
let's start with the very first feature
and that is to sync your notes with
local storage
in case it's been a minute since you've
used local storage or if this is the
first time you've ever accessed local
storage i created a little slide here
that should help you get started this
link up here will go to the mdn docs for
reference but essentially you'll be
using
localstorage.getitem and
localstorage.set item to interact with
the local storage api when you're using
getitem you provide a key and that key
is like an object a way to access the
data that you saved in local storage in
our case i'd probably recommend calling
this notes instead of key and then when
it's time to set the item in local
storage you will both access the key
where you want to save this and the
value that you want to save now it's
important to remember that value has to
be a string when it's saved in local
storage so if you have something that's
a little more complex like an array or
an object you'll need to use
json.stringify
to turn that array or object into a
stringified version or rather a json
version that can be saved in local
storage and when it comes time to pull
that out of local storage and use it as
regular javascript you'll need to
essentially reverse that by using
json.parse
so that brings us to the written part of
our challenge every time the notes array
changes in state you should save the
array of notes to local storage once
again i put here that you'll need to use
json.stringify to turn that array into a
string in order to save it to local
storage and as a second part of this
when the app first loads you should
initialize the notes state not as only
an empty array but instead with the
notes that are saved in local storage
since at this point you'll be pulling
things out of local storage you'll want
to use json.parse to turn that
stringified array back into a real
javascript array
now to avoid a kind of confusing bug i'm
going to add a little extra piece of
information here
your code for part 2 when you initialize
the state will go right here in place of
this comment but what i added was an or
empty array what that really does is if
you are trying to get data from local
storage and it doesn't exist it's going
to return undefined but we can't set our
notes array as undefined so if that does
return undefined it will instead use a
brand new empty array so i'll put this
back to indicate where you should be
adding your code for part two the last
thing i'll say is that this challenge is
a little bit trickier and it's because
i'm being a little bit vague i'm telling
you the feature i want you to add and
i'm giving you a little bit of a hint
onto how to actually code it but the
tricky part is that you are going to
have to reach back on the knowledge that
you've learned throughout this course to
figure out exactly how this should work
so the time is yours pause the
screencast and work on this challenge
the main thing that i left out for
challenge part 1 is that in order to
interact with the local storage every
time the notes array changes we will
want to set up a side effect in react
and of course that's what we do with
react dot use
effect i'll provide a function here for
the first parameter and the second
parameter i can add now because i want
this effect to run every time the notes
array changes
okay so every time the notes array
changes i want to
use local storage dot set item because
i'll be updating the notes key
inside of local storage and i can use
json.stringify to stringify the notes so
that my array can essentially be turned
into a string and successfully saved to
local storage
and i believe that's it for part one of
this challenge now that it's saved in
local storage part two is for us to
actually access that local storage so we
can in a way pre-load our app with
whatever notes we've previously saved in
local storage so here i can move this
onto its own line just to save a little
bit of room and we'll say i should
initialize state by accessing local
storage
getting the item with the key of notes
and because this will come back as a
stringified value i need to use
json.parse on the value that gets pulled
in from local storage
and you know what a small correction to
make if local storage is unable to find
anything at that key it doesn't actually
return undefined it returns null the
only reason that makes a difference is
because if you try to json.parse null it
will return null which is a false value
and therefore it will use the empty
array but if instead it tried to
json.parse undefined you actually get a
syntax error that would crash your
program so in that case it's probably
good that it returns null instead of
undefined
okay let's test this out i'm going to
clean up this challenge i'll hit save
and oh i was so close this should be get
item not get let's hit save again
okay we have no notes i can create one
even just creating that note should have
updated the notes array which means that
if i hit refresh awesome we're starting
with the notes that we left off on
if i
make a change to the note here and hit
refresh
those changes are here awesome if you
wanted you also could open your
developer tools go to the application
tab and see that you have local storage
that's being saved here on the scrimba
site now obviously local storage is not
a perfect replica of a real database
that will permanently save your data but
you can see in just a few lines of code
we were able to add a feature that made
this app much more usable than it was
before
so awesome work adding this feature
however there's one tiny thing that we
need to learn about to make this a
little more performant than it currently
is so we're going to take a quick aside
before adding any more features and
learn a new little fact about react
state
there's one little thing that i wanted
to talk about regarding how we're
initializing our state when we're
pulling from local storage like this now
of course whatever value we put inside
of react.use state here in the beginning
is just an initial value so really we
know that it will only set this value
when the app first loads after it loads
react is going to maintain any changing
state internally behind the scenes
however there is something that we need
to see and i can illustrate that by
creating some new state in this case it
really doesn't matter what it is we'll
just say state and set state is equal to
react.use state
the reason it doesn't matter is because
i'm actually going to put a console.log
statement which will run every time this
line of code runs
let's just put state
initialization
[Music]
i'll open up my console
and when i hit refresh
we can see that we get that console log
running state initialization but now i
want you to think about the nature of
react and what happens when any other
state in the app will change for example
if i add a new note anytime state
changes like adding a new note the
entire app component will get
re-rendered well if react is in charge
of saving the initial state in the
background then it might seem intuitive
that it's not going to run this line
again however if i maybe add a new note
we can see that it does run this line
again and that's because all that's
really happening is react is re-running
this entire function
in the background it is ignoring the
state that is trying to re-initialize
here but if there is code such as
running a console log or in our example
getting something from local storage
it's going to run that code again even
if it doesn't use the value as its new
initial state because it's maintaining
that state elsewhere in the background
now for direct commands in javascript
this is not a big deal at all for
example running this console log is so
minuscule in the amount of time it takes
for the browser to run this line that
it's completely negligible so even when
we're making changes
we're making changes here
you can see that it kept running that
state initialization console log but
because it takes so little effort for
the browser to run that code it's not a
big deal at all however something like
localstorage.getitem is a bit more of an
expensive call or rather it takes more
effort for the browser to dip into local
storage and get something every single
state change that happens in our app as
such react has implemented a way for us
to really easily make it so that any
expensive code that might be running
inside of our state initialization can
happen only one time and this is called
lazy state initialization it sounds a
lot more complicated than it is because
in the end all i need to do is instead
of providing a value i can provide a
function that returns a value so here if
i provide a function
that returns console log of state
initialization and let me put this down
onto its own lines here
i'll hit refresh
we get the very first state
initialization
but then
any changes i make don't
rerun that code
in the end this might seem a lot more
verbose than what we had but if we make
use of arrow functions and implicit
returns i can undo this to the way it
was
all i really need to do is put a set of
parentheses and an arrow even still this
is getting a little bit long so i'll put
this onto its own line so you can see
the whole thing but we get the same
effect i can hit save
and start
making more changes
to state which don't rerun our state
initialization console log now this
state was completely contrived running
console log inside of state is pretty
useless but it does lead us to our next
challenge
your task is to lazily initialize our
note state so that it doesn't reach into
local storage on every single re-render
of the app component if you were paying
close attention you'll know that this
will only require a few extra characters
on your part to type in pause now and
work on this challenge
all we should need to do is add a
function here at the beginning of our
call and have it implicitly return the
value that we had before just adding the
parentheses and the arrow should lazily
initialize this state so that it will
only reach into local storage the first
time the app loads in this case we may
not notice much of a difference
especially since we got rid of our
console log that we had before but we
can rest assured that this is going to
work the way we want i can hit save
which refreshes our app and it is
successfully pulling in the notes from
local storage
okay so that checks off this sync notes
with local storage feature that we just
added next we're going to think through
how we can add some more meaningful
summaries here instead of note 1 and
note 2. so let's do that in the next
challenge
next what we'll work on is adding some
real notes summaries as the title for
our notes instead of note 1 and note 2.
right now you can see when we're mapping
over the notes we grab the index and we
display note and then the index one
unfortunately this doesn't give our
users any idea as to the contents of
that note so your challenge is to try
and figure out a way to display only the
first line of the notes body property by
the way note.body is the text that is
showing up here in the editor and that
first line should be pulled out and used
as the summary that shows up here in the
sidebar the css should already be set up
so that it will truncate that so that it
doesn't wrap around really long in case
you do have quite a long first line in
your note and i've added a couple hints
here to help you along the way in the
challenge
first of all the text of note dot body
if you console log it will not show that
every time you hit return in the text
editor here it's actually inserting a
new line character let me show you what
i mean if we go to app and we're just
going to piggyback on top of this use
effect that is running every time the
notes changes
if i console.log notes at the index of
zero
dot body
and we open the console you can see the
text shows as if it were just a space in
between the note summary and the
beginning of the note line however if we
actually json dot stringify this
we can now see that there are two new
line characters that are sort of hidden
between that first line note summary and
the second line beginning of the note
and since we have a new line character
that can help us out your challenge here
essentially becomes one of a javascript
algorithm challenge so in reality it's
not even really a react specific
challenge i've given you a second hint
here that you can look at if you feel
like you need it i'm purposefully a
little bit vague in the language so that
if you need to you can go out to google
and try to find some resources that will
help you solve this challenge
speaking of which it's time to start
pause now and work on this challenge
hopefully while you were working on this
you came across the string.split method
while i'm testing things out i can
actually make use of what i have here
let's get rid of our json.stringify but
we'll just access the body of the very
first note in our array that's going to
be the string that we can run a split
method on
and the divider we can use is the new
line character which is backslash n
let's just see what this returns i'll
hit save open my console and awesome it
looks like we get an array that's split
on the new line or in other words it
uses the new line character to determine
when a new item in that array should be
created which means that if we just want
the first line of our note we should
just be able to access this array that
dot split returns by the zero index so
over in sidebar js i have access to each
individual note
and instead of this note with the index
we'll just insert some javascript with
our curly braces and we'll say note dot
body that's our string dot split
on the newline character backslash n
that will return an array and we'll just
say at the index of zero which should
access the very first line of our note
let's see how we did we'll hit save
and awesome look at that i suppose if
you want to get picky with it you could
remove the hashtag although if somebody
decides not to put this hashtag header
the way that we have maybe they wanted
to make this bold instead then we would
no longer have a hashtag to parse out
but instead some asterisks personally i
don't think it's that big of a deal
we'll probably just leave whatever
markdown marks end up in that first line
just as they are now i can see i'm
console logging everything because i set
that up here on line 18. i'm gonna clean
that up
and now if i change my note summary to
something else looks like that summary
is updating on every keystroke awesome
work
speaking of modifying the notes that
leads us to the next feature that we're
going to add and that is to move any
modified notes to the top of our list if
we had say 50 notes here and we scrolled
down to the bottom and modified one of
them that might be a good indicator that
we're interested in updating that note
more regularly let's say we instead had
i don't know maybe 50 different notes
here and we decide we want to make a
change to this bottom one we probably
want to bump that to the top of the list
so that it's more easily accessible
going forward so that's the next feature
we're going to add in the next
screencast
it seems like a sensible feature to add
to our app that if the user ever edits a
note in the sidebar it should pop up to
the top of the list so in an effort to
give you real practice on adding a new
feature all i typed out was what the
user experience should be and it's up to
you to figure out how to implement it
whenever the user edits a note
reposition it in the list on the sidebar
to the top of the list i suppose as a
quick hint i'll let you know that you
will have to refactor some of the
existing working code in order for this
to work pause now and work on adding
this new feature
we have a function that exists that we
can tap into whenever the user is
editing a note and that's our function
down here update note currently we're
using the map method so that the array
of notes stays in place in that array in
other words if they edit note 1 it will
always stay in the third position
because that's just how dot map works it
returns a new array where every original
item is at the same index in the new
array as it was in the original array so
if we're wanting to rearrange this array
there may be a way to use dot map to do
that however off the top of my head i
can't think of it and i'm guessing it
would probably be so clever that it
might be difficult to understand if
we're reading our own code or another
developer is reading this code in the
future so sometimes when i'm making
modifications like this what i like to
do is just duplicate and comment out the
code that was working and then even make
a note for myself something like this
does not rearrange
the notes
or something like that that will help me
remember what i'm doing
and then up here at least temporarily i
might say something like
try to rearrange the
most recently modified note
to be at the top
okay i'm still going to be running set
notes and i will still need access to
the old notes array but instead of
immediately returning the array that
comes back by calling dot map i think
i'm just going to start fresh
so let's see i think that's here yep and
to give myself some breathing room i'll
open up this function and honestly i
think the easiest way to do this might
be a pretty imperative way i'll type
this out as pseudocode to start so i'm
going to create a new empty array
loop over the original array
and if the id matches in other words if
the id of the note that we're currently
looking at in our loop matches the
current note id that we're saving in
state just like we have here node id
triple equals current node id then that
means it's the note that we're currently
editing and that means that i want to
put
the
updated note at the
beginning of the new array
if it doesn't match
so else
push the old note
to the
end
of the new array and after my loop is
all said and done
we will return
the new array hopefully that pseudo code
makes sense it makes sense to me but
that's kind of the point of pseudo code
write it so that it makes the most sense
for you and i like doing this as a way
to lay the problem and the solution out
and solve any issues i might see at this
point before i dive deep into the syntax
of the code that's required to actually
solve this challenge so let's do this
we'll create a new empty array we'll say
new array
we'll loop over the original array i'm
just going to use a good old-fashioned
c style for loop so we'll say i equals
zero
i is less than the old notes dot length
and i plus plus
move my pseudo code inside here so if
the id matches in other words if
old notes at i
dot id equals the current note id that
we're looking at in state
then i'm going to use new array dot
unshift to push a new item to the
beginning of the array and i can just
take my old code here
because i'm accessing the old note
the one issue with copying and pasting
is i have this object called old note
which i am not referencing anywhere in
my code so i'll need to change this to
old notes at the index of i before i get
too far down this road i really don't
like indexing into things a whole lot i
think i'd rather say
old note equals old notes at the index
of i and that way i can use old note
over and over instead of having the
weird syntax of the index there so as
we're looping through our old notes if
the id of the one we're currently
looking at matches the one that the user
is currently editing then add this new
object to the beginning which has the
updated text and all the old properties
just like we were doing before
but otherwise
we can just push
to the end of our new array the old note
because we don't plan on modifying it at
all
we can clean up some of these comments
then lastly we just need to
return
new array
as you can see this is a lot more
imperative with our c style for loop and
everything but let's hit save
we'll go to note 1
make any kind of modification like
hitting return
uh-oh looks like we have a bug here oh
and you probably saw this while i was
updating my old note here but i left
this as old notes instead of old note
little things like that will get you all
the time let's try this again i'll hit
save
note 1 hit return
awesome note 1 just pop to the top of
the list we can test this with some
other ones maybe i make a change here
and sure enough it's at the top of the
list and note 1 is still modified
and of course now it's at the top of the
list
awesome
at this point i can probably clean up
some of my comments if i'm not going to
be needing any of that old code or
anything like that although it might be
helpful for a future developer to
see that your code is written the way it
is because you want to put the most
recent change at the top so maybe i'll
just update this to say
put the most recently modified
well that should say note
at the top
awesome work and that does it for this
challenge the next and final feature
that we are going to add to this app
together is the ability to delete notes
so that's what we'll tackle in the next
challenge
the very last feature we're going to add
to our notes app is the ability to
delete notes i've made a few changes
since you last saw this app so let's
talk through those
first of all in the sidebar i added a
button that has an icon inside and this
icon has a trash icon that's a pure css
trash icon i didn't create this i copied
this from a site that has pure css icons
before you think i'm some kind of genius
in css and i set that up so that it will
only show up when you hover on one of
the notes so as i hover over the sidebar
note the little trash icon shows up
right now clicking it doesn't do
anything that's going to be your
challenge however you can see that
clicking the trash icon is also changing
the selected note in the sidebar and
that caused me to run into a bug and so
i started some of this code for you
we've got the function delete note that
will receive an event and a note id and
i wrote this line out for you event dot
stop propagation without going too in
depth what it does is it says when this
trash icon handles the click event
stop propagating that click event to the
parents like the sidebar div that's
holding this entire note in other words
this trash icon is a child element of
the note on the side here and so when i
click the trash currently it's
propagating that click event through to
the parent which is also handling a
click event now the fact that it is
still propagating that should tell you
that my trash icon is not correctly
using this delete note click event so
that's going to be part of your
challenge before i read through it let's
go to the sidebar you can see i
specifically indicated where you need to
add your on click event handler so let's
look at the challenge it's to complete
and to implement the delete note
function now i've given you a couple
hints here the first one is to think
about what array method you can use to
return a new array that has filtered out
one of the items in our case because
we're just deleting one item based on
some kind of condition hopefully the
language of that hint can give you a
pretty good indication as to what array
method you can use i also want you to
look closely at the parameters that
we're passing to delete note keep in
mind that normally on an event listener
we don't get to choose what parameters
we're passing so you'll have to find a
little workaround which we have talked
about in the past in order to pass both
the event object and the notes id and
this is the id of the note that is going
to be deleted as an aside the reason
that i had to do the stop propagation
isn't just because i didn't want to
select that note it's because i was
getting an error i would delete the note
and then it would try to select it as
the current note after it was deleted
and that was throwing an error because
that note no longer existed in my array
of notes
okay i've talked long enough now's your
chance to complete this challenge pause
the screencast and try to implement the
delete note function
before we work on the code here let's
test to make sure that we can
successfully add the event listener to
the trash icon button i'm going to just
add a console log that says deleted note
and then maybe i'll add the note id just
to make sure that i'm successfully
passing down the correct note and then
we need to pass this function down
through props to our sidebar component
we'll add a new prop called delete note
which will just be the delete note
function and then in the sidebar we're
already receiving props so i will add an
on click event handler here and your
first inclination might have been to
just pass props dot delete note here
however that's why i provided you the
hint about what parameters we're passing
to this function by default whatever
function we pass to an event handler
will receive the event as its parameter
and in order to pass something else
along with that i'd either need to do
some kind of magic with dot bind which
i'm not going to get into or more simply
i can say this is my function that i
want to call this entire anonymous
function and the first line or only line
of that function will call delete note
that way i can take the event that i'm
receiving as a part of the on click
callback function and pass it along to
my delete note function but then i can
also tell it to pass the notes id
remember we're here inside of dot map
and we have access to this note variable
which has an id property and that's what
we're passing down to delete note as
we're calling it i'll get rid of this
line here i'll hit save
let's open up the console and click the
delete icon here and awesome okay and
it's good that these ids are different
so that i'm not getting some kind of
captured value or anything weird like
that so now let's go to app.js and
finish implementing the delete note
function
i gave you a pretty good hint in my
first hint when i talked about filtering
out an item and that's because we are
going to use
array.filter but in our case we're only
going to filter out the one item based
on this id since i'm updating my state
i'm going to call set notes i do need
access to my old array of notes so i'll
use the callback function with old notes
as the parameter and i want to return a
new array that results from calling old
notes.filter
dot filter takes a callback function and
whatever we return from this callback
function needs to be a boolean to
indicate whether the current item we're
iterating over in the original array
should be included in the new array or
not so we'll say that for each note
we're looking at i want to make sure i
include items whose id property does not
equal the note id that we're trying to
delete this only has one parameter so i
can remove these extra parentheses
so once again we're looking at all of
our notes
we want to run the filter method
we're going to look at each note in that
array
and if the id does not equal the one
we're trying to delete then this will
result in true
which means i do want it included in the
new array that i'm returning from dot
filter which means essentially if it's
not the one that i click delete on it
will leave it alone and continue to
exist in the array however for the
onenote that i did click delete on
note.id will equal note id and therefore
this will be false and therefore that
note that i click delete on will not be
included in the array and thus it'll get
removed from my state
i'll hit save
let's click delete on note 2
and awesome we have note 1 and note 3
left i can click delete on note 3 and
note one we have no more notes in our
array if i hit refresh we're still at no
notes i can create notes and everything
seems to be persisting exactly as we
would expect
now i totally understand there were
probably two really difficult parts in
this challenge one was understanding how
to use dot filter in truth you don't
have to use that filter you can do
something a little more imperative like
what we did up here where we just
created a new array and manually
iterated over with an old style for loop
if you did it that way that's completely
okay obviously this dot filter gives us
a chance to do it in a really succinct
way but that doesn't necessarily mean
it's the only or best way and then the
other tricky thing that may have tripped
some people up was adding this callback
function that calls props.delete note
but as a quick reminder if you ever
really need extra parameters other than
just the event in your callback function
then you're probably going to pass a
whole callback function here instead of
just calling props.deletenote so that
you can pass whatever parameters you
want to your own function
and that brings us to the end of this
notes app hopefully you were able to
complete all of these challenges that we
worked on together i know that it's
difficult to jump into a new code base
and try to add features but there's
almost no better practice for you as
you're learning react than to jump into
an existing code base and try to figure
things out we've come a super long way
since we first started react so as a
final hurrah in this course the next
thing we'll be working on is the final
capstone project for this course and
this will be one that we create
completely from scratch since we're
going to be jumping into a new project i
highly recommend you really soak in
everything that you are able to learn
from this notes app and even go above
and beyond with it if you don't feel
like you've gleaned all the information
you could from this app then stick with
it try to add new features even try
something small like changing the design
of it to better fit your personal
preference then once you feel like
you've soaked up all the information you
can from this app we're gonna jump into
the final capstone project for this
course
here's the game we're going to be
building as our first major capstone
project if you haven't played tenzi's
before it's a dice game that's usually
better suited for younger children but
because of that the complexity is low
enough that it makes for a pretty good
project here the idea is to try and roll
10 dice that are all the same and in our
game you can click on one of the dice to
hold it and when you click roll those
held dice won't change we'll click the
other twos and we'll just kind of play
this game until all of the dice that we
roll are the same number
and as soon as we hold the last dice the
game is going to notice that we have all
twos it'll play this fun confetti drop
here it'll change the button from roll
to reset game and of course when we
click reset game it will start us all
over from the beginning the design for
the game can be found here if you click
this screenshot it'll send you to the
figma file for this game and i included
a little animated gif just in case you
forgot how this game is supposed to work
so you can reference this as well
feel free to peruse the code that we
have here you can see it's less than 100
lines of code in the main app.js
component which contains most of our
logic so get geared up to create an
awesome react project when you're ready
let's jump right in
all right we're starting from the very
beginning the only thing i've added is
some really basic styling for you and
i've included some google fonts for you
but there is nothing in our react code
at all so your challenge is to create a
brand new react app i want you to create
a separate app component that will live
in a separate file and then here in
index.js make sure to import that app
component and render it inside the app
component it should render a main
element and then for now i just want you
to style everything to look like the
basic outline for our game you can click
on the slide to go to the figma file
where you can find some of the design
elements well specifically this
background color so pause the screencast
and set up our tenzi's game
okay let's import the things we need we
know we need react from react
because we're going to be using react
dom we'll have to import react dom from
react-dom
while i'm importing things i'll import
app from a non-existent app file we'll
get to that in just a second and we'll
use reactdom.render
to render an app component and the place
we want to render it is in the element
that we get from getelementbyid root
let's create our new file for app.js
we'll import react from react
and export our component
like i said we'll have it return a main
element
maybe i'll just put something here so i
can see that things are working okay
pretty underwhelming now let's get to
some style i can see that from the
design it looks to me like the entire
body probably has this background color
and then the main element is this white
box here
so in the body i'll give it a background
color
which from the design we can see is this
color and since my main element is
essentially going to be the container
for everything i don't think i'm going
to bother with adding a class name
really i'm just going to have the main
element that i style and it looks like
that background color is not white in
the design it's
this very close to white color let's add
a little bit of padding to the body so
that there is that blue outline around
our main element we'll say maybe padding
20 pixels
i'll add a height to my main we'll say
it's maybe about 400 pixels i could
probably use a percentage or use view
height for now this will do the trick
and if i need to i'll come back later
and update that and then maybe instead
of a width i'll add a max width and say
something like 800 pixels because of the
padding we have we still have that
little outline on the sides the max
width makes it so that it doesn't get
too wide if we get really wide but i
don't think that's going to be a problem
that i'm going to be too worried about
right now
looks like we have a bit of a border
radius so we'll add maybe 5 pixel border
radius and there certainly will be more
styles that we decide to add to this
later but for now i think this is good
i'm going to get rid of my something
text here and awesome this is a great
start next let's see if we can add our
little dice components onto the screen
we won't worry about any data or
generating the numbers quite yet we'll
just get these components working so
when you're ready let's move on to that
the next thing we'll do is get some die
components rendered to the page for now
we'll just manually put in 10 instances
of our die component and in the end it
should look like this once again you can
click this slide to go to the figma file
so you can get things like the box
shadow and the font size for these and
everything the challenges written out
here create a die component this will be
in a separate file and that die
component should take a value prop or a
prop called value then inside of our
main here you'll render 10 instances of
the die component just manually and
provide a number between 1 and 6 for the
value prop on each one of those for now
and then make sure to style the main
component and the die component that you
create to look like they do in that
slide and just to make your css life a
little bit easier i added a couple hints
here i'd recommend making a container
that will surround all 10 of these dice
instead of just putting them directly as
children of the main element and that
way you can make that container a
display grid so you can make it always
display in two rows of five columns and
to get the separation between these
elements you can use the gap property
which will provide this spacing here and
then i would turn the main element the
one that has this white box into a flex
box so you can easily put that container
in the center of the screen okay pause
now and work on adding some dye
components that will display our dice to
the screen
let's start by making a new dice
component so i'll make die.js
sounds a little violent but that's the
correct singular of dice we'll import
react from react and export our
component
i know that this is going to take props
because we want to display a value prop
and looking at these dice because i see
this white outline around it that is the
shape of the die i'll probably actually
make this a nested element or rather
i'll
return something like a div
and inside that div is where i'll put
the text element itself let's call it an
h2
and this h2 is going to display props
dot value we'll get to styling this in a
minute but let's in our app.js import
our die component
i'll create that container that i was
mentioning
and let's just render 10 instances of
our die component we'll pass in a value
which we'll just start as one
and i'll just duplicate this ten times
okay let's see where we are
okay that's about where we expect to be
now let's start adding some styling
first let me create my grid here so i'll
give this a class name
let's say this is the dice container
and we'll set that up to be a grid
so display grid
give it a grid template and i'm going to
be specifying a height and width on each
of the die components themselves and so
i think what i'll do is just say this is
going to be two rows that are each auto
determined in their height
and then i'll use the repeat function to
say each one of the columns will be one
fraction unit wide and we'll have five
columns
let me actually refresh one of these
components here so i can see this
applying live
okay that's looking not too bad maybe
before i provide some styling here let's
go ahead and create the little dice look
around it so it has the white box i'll
go to dye js and this div here
let's give it a class name of maybe die
face since that's the face of each of
the die
and i'll save that and go to style.js
let's style up die face
and we'll give these a height of 50
pixels and a width of 50 pixels
i'm going to paste in a box shadow from
the design just so we can see the
surrounding area without actually giving
it a border
we'll give it a border radius
of 10 pixels
and then i want that number to be
perfectly centered in the middle so
let's make this
die itself display flex which will allow
us to justify the content to the center
and we'll make sure that we align the
items to the center as well
then in our container let's go ahead and
add a gap so we'll say a 20 pixel gap
so that the items can spread out a
little bit
okay i don't love how they're jammed all
the way up to the edges of my main
element so i think i'll add some padding
to my main
say maybe about 20 pixels
and then as i mentioned in the hints i
think what i'll do as well is make my
main a display flex
which kind of screws it up temporarily
but will set the flex direction to
column so that the elements are being
spread out top to bottom
and that will allow me to justify the
content to the center which allows me to
put that directly in the center
maybe for good measure i'll say align
item center i don't know that that's
going to make a difference well yeah it
actually pushed the items a little more
evenly spaced together so that was good
the last thing i think i'll do is add
cursor pointer
even though this won't necessarily show
up in the recording of the scrim if you
refresh this app you can see that it now
changes to that little mickey mouse
glove hand the only other thing i can
think of is these numbers are looking a
little bit smaller than i was hoping
so let me actually render dice with all
of the different values on a regular six
sided dice just so i can see a
comparison of the numbers and then i'll
give a class name to the number itself
we'll say class name is maybe die dash
num and we'll add some style to that
we'll say dot die dash num
let's give it a font size of
maybe two rims
is that too big let's see
it's pretty large but it really helps
highlight what the number is and since
that's the most important part of the
dice i think that'll probably be good it
also looks like these dice are blending
into the background i'm assuming they
probably have a transparent color so i'm
going to give them their own
background color of pure white and
awesome yeah that really makes them
stand out better
okay that was a lot of time being spent
on css but now what we can do is go in
and instead of manually putting in these
die components like this we probably
should be generating an array of 10
random numbers and mapping over that
array to create these die components so
that's what we'll do in the next section
of the project
we'll break up the generation of these
dice components into smaller challenges
this is a really good habit to get into
when you're problem solving instead of
being overwhelmed by a larger problem
like let's generate 10 random values and
create multiple die components based on
those values instead break that down and
say let's just make a function that
generates an array of 10 random numbers
and then we can tackle the creation of
the die components later so that's
exactly what we're going to do your
challenge is to write a function you can
call it all new dice that returns for
now an array of 10 random numbers
between 1 and 6 inclusive if you can't
remember how to generate a random number
in javascript a quick google search will
certainly help you out and then for now
let's just log the array of numbers to
the console pause the screencast and
write our all new dice function
a quick side note on algorithm
challenges like this i really highly
recommend that you try to come up with
your own solution i mentioned turning to
google to learn how to generate a random
number in javascript but for practice
sake i hope that you didn't just google
how do i create an array of 10 random
numbers in javascript instead i really
want you to put on your thinking cap and
try to find solutions on your own before
turning to google something like
generating a random number is not really
a challenge in javascript so much as a
syntax that you need to use but the rest
of this creating your function that
returns an array of ten numbers is
really a problem-solving challenge that
you should be practicing and not just
finding other people's solutions for
right away okay i'll get off my high
horse there i'm going to create this
function inside of my app component so
we'll say all new dice
and i think i'll break this problem down
into smaller parts so first of all i
need a new array to hold
my numbers
i'll probably need to loop 10 times
and as a part of that loop i'll need to
push
a random number
from 1 to 6 to my array
and then after the end of my loop
i can return
that array which will at that point have
10 new numbers in it and that should say
my numbers okay so we'll say
maybe
new dice is going to be an empty array
and then i can use just a c style for
loop should be fine i equals 0 i is less
than 10 i plus plus
we can say new dice dot push
and to generate a new random number you
have probably come across a solution
like math.floor
math.random
and then you can say times six
and then you have to add one to the end
of it and honestly i can't remember what
order these are supposed to be in but
instead of adding one if you want it to
not start at zero but start at one you
can actually use math.ceiling
math.random and i forgot my parentheses
there and the time 6 should be in here
so that was all kinds of problematic but
the point is this will create a random
number from 1 to 6
and then once that number is created it
will push it to the new dice it will do
that 10 times and at the very end i can
just return my new dice array get rid of
my pseudo coding planning comments
and then let's go ahead and console log
what comes back by calling all new dice
open my console hit run
oh and so close and you probably saw
this when i typed this out it should be
new dice not new nice
okay
cool all of those numbers are between 1
and 6 inclusive and there are 10 of them
so awesome that probably does it for
this challenge in the next screencast we
will take this array and we'll turn it
into actual dice components
all right here's the next part of the
challenge from before let's make use of
the all new dice function that we
created and create new state to hold
this array of numbers and in fact when
you are initializing state you can set
its initial state to be a call to the
all new dice function and that way as
soon as the component loads it will
generate all new dice for us right at
the beginning then with your brand new
state you should map over that array and
generate the array of die elements that
we will use to replace the manual 10
items that we wrote here
pause now and work on this challenge
okay let's create some state here at the
top of our component we'll say
maybe we'll just call this our dice and
set dice
and that's react.use state we're going
to initialize the dice state by calling
our all new dice function
and then to generate the array of dye
elements by mapping over our dice i
could either do it directly here inside
of my return i could put my curly braces
to put in some javascript and say
dice.map whatever i personally prefer to
generate an actual variable that holds
that array of die elements but outside
my return really only because it helps
me separate the logic a little bit
either way is completely fine so i'll
say const dice elements equals die stop
map i'm going to look at each individual
die and i'm going to return a die
component
with the value prop
set to the number of that die now
remember right now we're just iterating
over an array of bare numbers and so
here die really just represents the
number itself and now dice elements will
be an array but instead of an array of
numbers it will be an array of die
elements with the value prop set to the
same number as the item at the same
index in the original dice array now i
can just render this dice elements array
right down here before these were hard
coded and we could see it went one two
three four five six and then a bunch of
ones now when i hit save we should get a
bunch of random
numbers that show up here in fact it
should be random every time i hit save
we'll get a different set of numbers now
because we're mapping an array into an
array of components react is warning us
that we need to provide a unique key
prop to each of these elements right now
we actually don't have a great piece of
data to use as a unique key prop but
later down the road when we refactor our
dice elements that are in this array
from a set of numbers to a set of
objects we'll come up with a solution
for providing a key prop here however
that's not the next step we're going to
take instead we're going to create a
button that will allow us to re-roll all
of our dice so that we can roll our dice
without having to refresh our
application so for now we'll ignore that
warning but we will solve that in a bit
when you're ready let's move on and
create our roll dice button
the next thing we want to add is a roll
button that when it's clicked will
generate all 10 new dice for us down the
line we'll be modifying it so that we
can hold dice that are exempt from this
roll button but for now just make it so
that it rolls all new dice
you can put your button right here below
the dice elements and well the rest of
it i'll let you figure out pause the
screencast and work on this challenge
first i will create a new button
and we'll just have it say roll actually
let's just hit save and see where that
gets us
and as a reminder we will be having this
warning every time we hit save we're
going to address that really soon and
well that's pretty abysmal in terms of
styling but it looks like we've got a
button there maybe let's hook it up
first and then we'll style it clicking
the button should run a function that
will generate new dice by using set dice
and we could probably just combine our
all new dice to determine what the new
dice are so i'll go ahead and create a
function called roll dice
and this will just call set dice and for
now we don't care what the old dice were
we're just generating all new dice so
we'll just run all new dice to generate
the new numbers and then let's connect
the roll dice function up with an on
click handler
okay i'll hit save
and when i click roll awesome we're
getting all new dice well that was
simple enough now let's add some style
to our dice i'm going to add a class
name to the button
maybe let's just call it
roll dice
and then we'll add some styles
to the roll dice class and i'll mostly
just be following what we have here in
the sigma design i think i'll set the
height to about 50 pixels the width to
about 100 pixels
and i might need to hit save so these
can apply live yep there we go
we'll take away the border with border
none but it does have a border radius
about maybe six pixels
it's got a background color that we can
find in the design
and we just need to spell that right
there we go
the text color is white so we'll change
the color to white
looks like the font size is a bit larger
let's call it 1.2 rims and if i remember
right buttons i believe don't take on
the correct font family so let's grab
the font family and oh it looks like we
never set the font family on the body
let's go ahead and do that now i'm using
this carla font that i'm bringing in
from google
okay we can see that making a difference
we're going to do the same font family
on our button
now this i don't think is the greatest
practice for accessibility but just for
our visuals right now i'm going to take
away the
outline whenever the button is focused
so we'll say outline is none and this
wasn't something in the design but it's
a nice little touch i'm going to add an
active class which means when you're in
the process of clicking the button it's
going to add this inset box shadow and
that will just make it so that
it looks like it's being pressed or
indented into the screen which is kind
of nice
now right now our spacing is a little
funny let's go ahead and fix that i
think one way i could easily do that is
to
instead of doing justify content center
i might try space around
and it puts our numbers a little bit
high especially when eventually we're
going to have some text up there but
when we add the text it might rearrange
everything in a pleasing way so for now
i think i'm okay with the way it is and
yeah i should be able to click roll and
everything is working great again in the
recording you won't see this but i think
i also will add the cursor pointer
just to make it very clear that it's a
clickable button and awesome great job
at this point it's a great idea for you
to do a little self-assessment and see
if you were able to accomplish that
challenge all by yourself everything we
did in this challenge should almost be
second nature to you now based on the
amount of repetition that you've had the
opportunity to do if you did struggle
with this challenge now would probably
be another great opportunity to jump
back in the curriculum re-watch some of
the lessons that we've done and more
importantly redo some of the challenges
that we've assigned to you and that way
when you come back to this roll dice
button challenge you can do it
comfortably without it being overly
difficult
and then of course whenever you're ready
the next thing we're going to work on is
being able to hold the dice so that when
we click roll it does not change the
dice that are held and that's the
challenge we're going to tackle next
the next thing we'll work on is the
ability to hold dice in place so that
when the roll button is clicked those
dice that we've held don't change
up until now we've been saving just bare
numbers or integers in an array but in
order for each dice to also contain
information about whether or not it's
being held
we'll want to change those to an object
so that is your challenge here update
the array of numbers and state to be an
array of objects instead those objects
should have a value property which
contains the number of the dice or
rather the number that is being
displayed on each die and an is held
property which we will default to false
don't worry about styling the dice or
fixing the roll button quite yet we're
going to do this over the next few
challenges but simply making this change
from an array of numbers to an array of
objects is going to break other parts of
our code so the next part of your
challenge is to bring it back to a
working state pause the screencast and
work on this challenge
i purposefully didn't show you exactly
where these changes need to be made so
that you would have to do some thinking
about it the place where we are
generating the numbers and pushing them
to the array is right here we're
creating a new array and just pushing a
number that's randomly generated so
let's simply update this line of code
instead of pushing a number i'm going to
push an object with a value property
that contains that number and an is held
property
that contains a boolean will default
every one of them to false
i think i'll put these on their own
lines so it's a little bit easier to
read
and now every time we call all new dice
we are creating an array of objects that
means down here when we're mapping over
our array of objects and die is no
longer a number but is an object the
value needs to be die dot value let's
hit save and see how we did okay well we
still have our warning from react about
adding a key property we're going to
work on that in just a second but let's
test to make sure that everything is
working and awesome looks like we're in
a good place
now the next thing i'm going to do wades
into deeper waters of intermediate or
advanced react so i'm going to explain
it in a very surface level way but just
know that for now it's not terribly
important that you truly deeply
understand exactly what we're going to
do i want to address this warning that
we're getting where each child in a list
should have a unique key prop when
you're pulling data from an api and it
receives some sort of unique id
generated by the database that's perfect
that is the id that you should use for
your key prop in our case we are not
receiving that because well we're not
calling out to a database at all we're
generating these objects on the fly now
the reason this key prop is important in
the first place is so that react has a
good way to keep these in the correct
order in case anything were to be
removed or added to this array in our
case we will always have 10 items in
this array and we don't plan on removing
or adding any new dice to our game here
so one solution is to get a third party
package which i can add as a dependency
i'm going to add one called nano id
and nano id is just a really fast way
for me to generate a random id on the
fly in my code what i can do at the top
is import
nano id
from the package nano id
and then every time i'm creating this
object i will create a new id property
and just call the nano id function let's
take a look at what this generates for
us so i'll console log new dice and open
my console we'll hit save and you can
see the ids are a little bit crazy
they're not just like one two three four
and five but there's enough bits in that
id that we can essentially be guaranteed
they will be unique and now that i have
an id i can fix my warning and just say
my key on these die is going to be die
dot id
let me push some of this onto its own
lines
i'll also remove my console log here and
now i should be able to
get rid of my warning awesome
okay so now every one of our dice has
the ability to know whether or not it's
being held
but we currently have no way to change
that so that's what we'll start
addressing in the next part of this
project
very soon we'll be working on making it
so that every die knows that when it's
clicked it should toggle its held
property from true to false or false to
true but for now let's add some styling
to the die so that if it is held it can
put this green background color that's
going to make our job a lot easier to
test when we add the clicking ability
for holding or unholding a die to test
that i'm going to change the dice from
is held to false to be is held to true
so that when you work on your challenge
you'll be able to see all the dice
turning the light green color assuming
you got everything set up correctly so
your challenge is to add some
conditional styling to the die component
so that if it is held or rather if that
dies is held property is true its
background color will change to that
light green color which you can
reference the hex code for right here
don't forget that currently the die
component has no way of knowing whether
or not it's being held so that's
something you'll have to address as you
work on this challenge once you have all
the dice with that green background
color come back to our all new dice
function change this from true back to
false and refreshing the app should then
clear out the green colors and it should
look the way that it does right now so
pause now and work on this challenge
i think i might work a little backwards
in this challenge because first i need
to let the dye component know whether or
not it's being held down when i am
mapping it i'm passing a key prop which
isn't really usable except for
internally by react and i'm passing this
value prop i'm going to also add an is
held prop and that is just going to be
the value of die dot is held so either
true or false or in our case all of them
will be true because that's how we hard
coded this that alone shouldn't really
break anything in our code but if i go
to the die component i now have props
dot is held and i can use that to
generate my background color
to do some dynamic styles i'm going to
create a separate styles variable
although this could be something that
you handle in line right here by saying
style equals and then an object i think
that gets a little bit lengthy
especially if you're adding more than
one style so for now i'm going to say
style equals my styles object that is
defined up here separately and then i'm
going to
set the background color this has to be
camelcased remember because we're
accessing the dom properties of this
element
and here i can use the ternary i'm going
to say props dot is held
if it is held then i want to use that
hex code that we saw before
but otherwise i want the background
color to be white
let's hit save
and awesome we get all green dice just
like we expected for one final test back
in app.js i'm going to change this back
to false hit save
and that has cleared out perfect
i suppose that technically means that my
die
face no longer really needs a background
color that's set in the css because that
will be handled with an inline style
here in react maybe i'll just double
check that refreshing gets me all white
dice and when i change this to true
all green perfect
wow that's a lot of twos on one roll
that's amazing it's too bad we're not
playing this game yet
okay i'll set this back to false because
that's where we really want our game to
be
and perfect now we're ready to start
tackling the challenge of having each
die be able to hold when it gets clicked
so we'll start working on that next
in the past we've talked about something
called derived state and how for the
most part it's not something you'll end
up using very often as a reminder i've
brought in this diagram which we've seen
in a past lesson and adapted it to work
for this tenzi's game we're making in
this game we have our app component
which is holding an array of dice
objects and it's mapping over that array
and creating instances of our die
component
it's then passing the is held property
down so the die knows how to display
whether it should be green in the
background or not and in this diagram
what we see is each dye component
containing its own state which is
initialized by its incoming prop of is
held and then having the ability to flip
that is held property from true to false
or false to true although this might
generally accomplish the goal of making
each die be able to flip from green to
white or white to green it breaks our
game because if each die component has
its own state of is held it isn't
necessarily communicating that change up
to the parent state and in our game we
need to be looking at every single die
so we know how to end the game if every
die is held and every die has the same
number then the game is one however if
each die is flipping its own state like
i said there's nothing communicating to
the parent array state that it's
changing so a much better way for us to
structure this although it may include a
little bit of extra code is to not put
state on any of these components and not
have them be able to flip that own state
that it initializes from its incoming
props or in other words using derived
state instead we will only keep the
state on the app component we'll create
a function that we'll call hold and that
hold function will be passed down to
each one of the die components
in our case we need to know which die
clicked hold and so that hold function
will receive an id as a parameter if you
remember when we are generating our dice
we create an id property for each one
which is unique and as such it's
something we can pass as a parameter to
our hold dice function so that brings us
to your challenge your challenge is to
create a function we'll call it hold
dice that takes an id as a parameter and
for now don't worry about the logic of
this function just have it console log
the id that's passed in as a parameter
and then i want you to figure out how
you can pass that function down to each
instance of the die component so that
when any one of them is clicked it will
log its own unique id property in other
words you need to make sure that when
you click the first die it shows a
different console log than when you
click the second die in truth there's
more than one way to make this work we
have looked at multiple different ways
to make this work in the past so you can
just choose whichever one makes the most
sense to you so the time is yours pause
the screencast and work on this
challenge
okay let's create a new function we'll
just do it right down here
hold dice
and let's spell function correctly this
will take an id as a parameter
and it's just going to console log the
id
easy enough now when we are mapping over
our dice objects and creating our
instances of the die component i
basically have two different ways i
could do this one thing i could do is
pass the id to the die so this would be
die dot id and then also pass hold dice
as the function
holds dice
and then inside of the die component i
could call hold dice on click and pass
the id that's passed as a prop here
however to me this is one additional
step without really a lot of noticeable
gain and so i think i'm going to take
that out and then what i can do is just
create a new function and say hold dice
is going to be this anonymous function
and this anonymous function will call
hold dice with die dot id as its
parameter
effectively what this is doing is
embedding the id as the parameter that
will be called with the hold dice
function whenever each one of these dice
is clicked
so i should be able to hit refresh and
of course at this point clicking the die
isn't going to do anything because i
haven't actually accepted that prop on
this side so now i'm receiving a prop
called let's see it was hold dice here
and i can add an on click to my div i'm
going to separate these onto their own
lines
on click equals props dot hold dice so
let's hit refresh
i click the first one and i get this id
that starts with hg
this one starts with a y z
yjb awesome specifically i'm checking to
make sure that these were all different
from each other if they were all the
same then something would have happened
incorrectly as i was passing in the id
but they're all different which means
each one of these has their own function
that can identify which die was clicked
so that in the next part of this
challenge we'll be able to update our
state which is holding all of our dice
to flip the held value or the is held
value on just the die that was clicked
so that's what we'll do in the next
challenge
the next thing we're going to work on is
making it so that clicking each die will
actually flip its is held property
instead of just console logging the id
again the goal is to make it so that i
can click the die that i want to hold
have it flip its property which
therefore will change its background
color and then coming up in the future
when we click roll we will create new
dice for all of those except for the
ones that are held
so your challenge is to update our hold
dice function to flip that is held
property again you'll want to keep your
dice array almost exactly the same way
as it was except for the one item that
was interacted with based on this id as
usual there's more than one way to
accomplish this i'm going to be using
dice.map and checking for this id while
i'm looping over the dice inside of my
callback function index.map but honestly
if that way is confusing to you you can
just do this whichever way makes the
most sense to you
pause the screencast and work on this
challenge
okay to update our state we will need to
use our set dice function so i'll start
with a call to set dice
i do need access to all the old dice or
the old array before we make this change
so that i can determine what the new
array should be and i'm going to use the
map method to create a new array or
return a new array from this function
and again almost every die object is
going to be exactly the same way as it
was except for one of them which will
just have the isheld property flipped i
remember when i first learned about this
way of updating an arrayed state it felt
i don't know inefficient or something
but in truth javascript does these
operations so quickly that it doesn't
even blink at something like this so
inside of our map we're going to look at
each die object we'll have another
function and i think this time i'm just
going to open it up so that i have some
breathing room on the next line and here
i can use a ternary that says if it is
the same die with the id property that
was passed in to the function then i'll
update that object and if not i'll just
return this die
i can do that by saying return and then
use my ternary to say is dye dot id
the same as the id passed in if so and
that's the one we want to change and i'm
going to take all of the properties from
the original die but update is held to
be the opposite of
die dot is held
i'm going to move this on its own line
and then put my else with this colon and
start the next part on the next line and
i'll say if it's not the id that we
clicked on or that we interacted with
just keep the same object that we had
before and i think this should do it
let's hit save and well we have a lot of
pairs here let's just do the twos
awesome i should also be able to change
my mind click off the twos and choose
the sixes instead
great
this was one of the major features that
we needed to add to this game the next
thing is we need to make sure that when
we click the roll button we don't just
lose all of our dice but instead roll
only the dice that we didn't hold
so that's the feature we will work on
next
other than checking if the game has been
won i think this is the last major
feature that we need to add to this game
so your challenge is to update the
rolldice function instead of just
creating all new dice every time we
click the roll button that instead you
will look through the existing dice and
not re-roll any dice that have been held
as a hint this is going to look
relatively similar to what we did in the
hold dice function at least the way that
i'll be solving it of course if you find
a different way that you prefer or makes
more sense to you then just go with that
way that'll be great when you're
creating new dice as a part of that role
remember to use the id that we are
getting from nano id that way any new
dice you create will also have an id and
therefore will work when we click them
to hold them pause the screencast and
work on this challenge
ok instead of creating all new dice we
do need to now be looking at the old
dice so we'll pass a callback function
here to set dice instead of just
generating a new value for it
and we'll create a new array by calling
old dice dot map
we'll look at each one of the die in the
old dice
and similar to before what we'll do is
check the die dot is held property and
if the die is being held we want to make
sure we just keep it as part of our
array if it's not being held however we
will return a new die to add to our
array now looking a little bit ahead i
can see that here i'm creating a new
instance of a die down here i'm
essentially going to be doing the same
thing i could just copy and paste this
value however this raises something
called a code smell for me i can see
that we're going to have repetitive code
so this wasn't technically part of the
challenge but i think what i'm going to
do is create a separate helper function
that's called maybe generate new die
and i'm just going to have it return
let's see this object right here
and that way anytime i need a new die i
can just call this function
i think i'll move this up above my all
new dice so it's a little easier and
more logical to read
then right here i'll probably call
generate new die
and down here i'll do the same thing
we'll just say generate new die
again that wasn't really part of the
challenge so if you didn't make this
helper function that's completely okay i
just thought i'd show you how i might do
it if i were looking ahead and seeing
how i was about to have some repetitive
code let's cross our fingers
refresh looks like we have three twos
here so i'll probably start there we'll
hit roll and awesome everything rolled
except for the three twos that i held i
could then hold a couple more twos
getting a little bit unlucky with our
rolls here there we go get a couple more
twos in here
there's another one we're almost done
there it is
so that brings us to the next challenge
how do we end this game
of course me clicking this doesn't make
any difference to the game at all i
could click roll but nothing's going to
re-roll and we basically haven't told
the user anything about whether they've
won or not
speaking of telling the user some things
i think just really quick i'm going to
paste in some elements that will give
some additional information to the users
if you remember in this original
screenshot we have the title of tenzi's
and a little description i'm going to
add those in now and just paste them in
from somewhere else because they're
pretty straightforward
as you can see we just have an h1 that
says tenzis a paragraph with some
instructions both of which have a class
name so that i can add some code in our
css to style them
i'll hit refresh i think i'll probably
put a little bit of margin below our
let's see dice container
we'll say margin bottom maybe like 40
pixels and yeah that's looking better
okay now let's get back to the next
challenge where we will start actually
informing the user whether they've won
or not
we're going to break this up into a few
different screencasts and just take this
one little byte at a time
your challenge this time is to add some
new state called tenzis and you'll
default it to false
this new state will represent whether
the user has won the game yet or not
then i want you to add an effect that
will run every time the dice array in
state changes for now you can just
console log dice state changed and not
worry about doing anything else if it's
been a while since you've gone through
the curriculum on use effect this would
be a great time to go back and review
and once you're ready pause the
screencast and work on this challenge
okay so i can create some new state
we'll say tenzi's
and set
is equal to react.use state and we'll
initialize it as false
that way they won't win the game as soon
as they load it and then we're going to
add a side effect and we'll use that
with react dot use effect
use effect will take a function as the
first parameter
and i'll set up the second parameter
right now because i only want this
effect to run any time the dice array
changes in state
as i mentioned for now we'll just
console.log
dice state changed
so let's hit refresh
we get a dice state changed on the very
first load and then it should every
single time i update the dice array
even if it's one small change like
changing one of the dice to being held
then we get our effect running also if i
run my roll button that also gives me a
dice stay changed awesome
now it may not have been perfectly
apparent why we're using an effect here
and that's mostly because we only did
about half of this challenge right now
in the next challenge what we'll do is
we're going to check all of the dice
every single time something changes in
the dice to look for a winning condition
and if the game has been won for example
if all the numbers are the same and all
the dice are held then we can set tenses
to true and therefore the user will win
the game
keeping two internal pieces of state in
sync with each other is a really common
reason to use a use effect we talk about
it being a side effect as if it only
concerned things outside of this
function entirely but keeping two pieces
of internal state in sync is another
good reason for it
so this one was short and sweet but in
the next screencast we will make it so
the user can actually win the game
your challenge this time is inside of
our effect instead of console logging i
stay changed you'll check the dice array
for some winning conditions first we're
looking to see if all of the dice are
currently held and that all the dice
have the same value if both of these
conditions are true then set tenses to
true and log something like u1 to the
console pause now and work on this
challenge
just like before there are a ton of
different ways that you might have
solved this one hopefully the way that i
solved it will ring true to you but if
you found a different way or even a
better way then feel free to share it in
discord i would love to see people's
different solutions for this in
javascript there's a really handy array
method called dot every
and what dot every does is it will look
for a specific condition and if every
item in that array returns a true for
that condition then it will as a dot
every method return the value true this
might make more sense if i actually show
you i can check dice.every and for every
die
if every die
dot is held or in other words if every
die has true as an is held property i
don't necessarily need to say triple
equals true though then dice.every will
return true if even one of the dice is
not being held then it will return false
so i can save that boolean that it
returns as a variable will say all dice
held or just say all held and that's
either going to be true or false so
that's a good start to help me have an
if statement later that checks if
they're all held and if they all have
the same value now how can i check to
make sure that they all have the same
value well if they all have the same
value then i can just arbitrarily pick
one of the dice and check all of them to
see that they have that same value for
example i could say maybe the first
value
is equal to dice
at the index of 0 dot value and now i
have a reference point for me to say
maybe all same value is dice.every
and i'll say every die dot value is
equal to the first value
and now i have some variables that i can
check inside of my if statement whether
or not they're all held and if they all
have the same value
so we'll check if they're all being held
and they all have the same value
then i need to set tenzis to true
and we were going to console.log u1 i'll
just reuse this console.log here
all about recycling you won
now you may have asked why am i going to
set tenses to true there's a few things
in the user interface we're going to
change if they have one for example we
won't want the button to say roll
anymore we might want it to say reset
game and we can conditionally render
that text based on the tenzi's value and
as you might remember from the preview
we have a fun little confetti thing
that's going to pop out when the game is
over but we'll save that as a special
treat at the very end so let's hit
refresh and actually play this game and
oh well it looks like we might have a
bug here
ah and after a quick look it looks like
i did not put a callback function inside
of my dot every sorry for anyone who was
screaming at me saying i did that wrong
okay let's try this again i'll hit save
okay we're back up to working and oh
look that's a great start we got six
sixes that's amazing okay we'll hold all
those
awesome we're making good progress
and we should get our state
updating finally whenever i finally roll
another six
as a side note i feel like this is how
every game of tenzi's for me goes it's
the very last one that i never can get
to be the right number there we go okay
let me open the console
you won awesome keep in mind this effect
was running every single time the dice
array changed which means it ran every
single time i clicked on one of the dice
and every single time i clicked my roll
button awesome we have come a long way
the next thing we're gonna do is update
a couple user interface things one is
just procedural that's where we're gonna
update this roll button and the next is
we're gonna have a lot of fun with the
confetti package both of those should be
really simple for you at this point as a
reminder if you were not able to create
some version of this it didn't have to
be these exact methods but if you
struggled with this challenge it's time
to erase it and try it again make sure
you understand this before we move on
the last two things we're going to do
are more just checking boxes but the
ability to complete a challenge like
this on your own without any kind of
outside help will be a really good
self-assessment for you to know whether
or not you're ready to move on so when
you are ready let's tie off the little
loose ends of this app and call it done
okay it's time to tie off a few loose
ends inside of our tenzi's game this
challenge comes in two parts first of
all if the tenzi's in state is true i
want you to change the button text down
here to say new game instead of roll
secondly and probably the more exciting
of the two challenges is that if tenzi's
in state is true to use the react
confetti package to render a confetti
component i've already included the
react confetti package for you and down
here in the slides i included a link to
the documentation for react confetti i
think you'll find it's actually a really
easy package to use in the end you're
just going to need to import confetti
from react confetti and then to render a
confetti component now in our case we
will only conditionally render that
confetti component based on the value of
tenses also in the documentation you'll
see that they provide a height and width
properties you just won't really need to
worry about those in this case in the
end once you have the confetti package
conditionally rendered upon winning the
game it should look something like this
where the user completes the game and
then a bunch of really fun confetti
falls down
okay these are some fun additions pause
the screencast and work on these
challenges
okay let's start with number one if
tenses is true change the button text to
new game well let's go down here to our
button i think i'm going to put some of
this on its own line so we have some
extra space while we're looking at it
and instead of hard coding roll in here
i'm going to put some curly braces so i
can use a javascript expression and
we'll use a ternary because we're
choosing between one of two options
either the word role or the words new
game
so i'll say if tenzi's is true question
mark then we want it to say new game
and otherwise we want it to say roll
okay let's
save that
and we need to spell tenzi's correctly
of course
okay let's see we've got well it's not a
great first roll let's go with some ones
and i'll play through this quickly so
you don't have to watch me do this whole
game
okay so clicking the last one should
change tenses to true and change role
into new game let's see if that works
awesome well i don't love that it's
stacking on top of each other i think
i'll just go into the css and let's find
my
button here and i think it's this one
let's try making that 150 pixels yeah
that looks better
okay and then part two of the challenge
is to render the confetti component if
tenzi's is true like i mentioned i
already included the react confetti
package but i do need to import the
confetti component from react confetti
and again we're only conditionally
rendering this and i included a little
note here that tells you exactly where
to render it i'll keep my curly braces
so i can use some javascript and this
time i'm just going to be using the
logical and operator because in this
case i either want to render confetti or
i don't want it to render at all so
we'll say if tenzi's is true
then we will render
confetti
i'll hit refresh
and at this point there's something
important for you to know about this
recording at the current time scrimba is
not really able to record anything that
happens on a canvas element which is how
this confetti is being played so i'll
play through this game and i'm going to
see the confetti work you'll be able to
also refresh this app and see the
confetti work but in the recording it's
not going to show up so once again i'll
speed through this game play so you
don't have to watch the whole thing
okay so i will click the two and sure
enough i can see the confetti dropping i
assume if you completed this challenge
correctly you also were able to see the
confetti dropping or if you struggled
with it well first of all i'd encourage
you to go back and try it again but
second of all you can click to refresh
this app now with the code that i've
written and play the game and see that
the confetti is working now at this
point i'm pretty sure we still have a
bug in our game and that's if i click
new game yep look at that it says that
we won again and nothing has really
refreshed or anything so we'll have one
more challenge before this project is
complete and we're going to handle that
in the next screencast
here's another example of a challenge
that i'm going to be a bit vague about
because i want you to think through what
steps are going to be necessary to
complete the challenge on your own so
the task is to allow the user to play a
new game when the button is clicked and
they've already won i won't necessarily
play through this entire game again but
you saw that when we clicked new game it
just console logged u1 again and i want
you to think through why that is and
what you can do to fix it so that it
will reset the game pause now and work
on this challenge
as it stands clicking the button will
run the roll dice function currently
there's nothing in the rolldice function
that will check if they've already won
the game now we could choose to create a
completely separate function that will
create a new game for us which would
require us to then conditionally render
one of two buttons based on whether they
have already won or rather based on
whether tenzi's is true or not right now
we're only changing the text of the
button when tenzi's is true but we're
not creating a completely separate
button with a different on click handler
either way would probably be fine i
think i'm just going to update our roll
dice function to handle the instance
when the user wins the game
now i really want them only to roll the
dice if
they don't have tenzi's if the game is
not over
so i'm going to move this code into if
tensei's this conditional block here
and then i can add an else that says if
tenzi's is true in other words if
they've won the game then first i want
to set tenzi's to false because i don't
want the game to still be one and then i
can generate all new dice so i'll say
set dice and i previously wrote a
function called all new dice
that i can use to generate all my new
dice
okay now let's play through the game one
more time and see if we can get this to
work
we'll start with our fours this time oh
i'm gonna switch to sixes because i have
more of those
okay here we go
okay it says new game we got that
console log which we can probably get
rid of
of course the confetti package is
celebrating our win
and then i click new game and everything
restarts and wow look at that five fours
right off the bat
and at this point we have reached the
end of our journey together building the
tenzi's game however that doesn't mean
it has to be the end in the next
screencast i'm going to give you some
ideas on how you might improve this game
quite a bit more if you really want
something that you can feel good about
putting in your portfolio we won't walk
through how to create those features but
it could be a really excellent way for
you to practice your skills instead of
just moving forward i hope you've
enjoyed this tenzi's game it might not
be quite as fun to play against the
computer but if you have some dice
laying around i do recommend playing
tenzi's it can be really fun and high
energy especially when you're just
trying to get that last dice to read the
number that you need and you're racing
against other people so on that note
let's take a look at some ways that you
might be able to improve this project
just because we have completed the
tenzis project together does not mean
that the fun has to stop there assuming
you enjoyed this project even a little
bit i'd highly recommend that you spend
some time adding to it the process of
adding new features to the program that
we made together is going to expand your
mind and really help you internalize the
things that we have learned together
thus far
i came up with a couple ideas you are
welcome to use them or to do something
completely different some ideas for
extra credit on this project include
adding real dots on the dice right now
we're just using numbers for simplicity
in the css but if you really want to
challenge yourself with some css figure
out how to put real dots on the dice
more on the javascript side you could
decide to track the number of roles that
it took to win the game along those
lines you could track how long it took
to win the game and then you could save
your best time or maybe even the lowest
number of roles to local storage so you
can try to beat your record in the
future
obviously this is not all-inclusive be
creative add whatever you want to this
project in the end being able to show an
employer that you not only took a
project that you built together in a
tutorial but also added a bunch of new
features on top of it that's going to be
much more impressive on a resume and a
portfolio than a project that you just
sort of followed along with great job on
the tenzi's game you should really be
proud of yourself and assuming you were
able to follow along with everything and
that you would even feel comfortable if
you know we needed to delete everything
and start from scratch that's an
excellent sign that you have really
learned what you need to learn from this
react course
if you look back it's pretty insane how
much ground we have covered so far so if
you think about it this is the ultimate
solo project for this course
it's going to collect all of the topics
that we have learned throughout this
course and put it together into a single
project so you can really test yourself
to see if you have been internalizing
all of this new react knowledge that
you've been learning
and this project is a really fun one
you're going to be creating a trivia app
called quizzical it'll have an opening
screen here where you can click to start
the quiz it will then pull some trivia
questions from a database and display
those as a short quiz once the user has
made all of their selections they'll
click check answers and the app will
score the quiz and allow them to play
again if they want
clicking on any of these screenshots
will send you to the figma design file
you can see the three different screens
here just to be clear this first screen
will actually be almost like a separate
screen it's sort of an overlay when
someone clicks start quiz you'll
probably want to conditionally render
this next section but this third screen
is not really a separate screen it's
just changing the first screen so that
it gives feedback to the user on the
quiz answers
as always make sure that you go in and
duplicate this to your draft so you can
avoid seeing everyone's cursors or
selections and so if you want you can
make any edits to the design and just
like before you can click the three dots
down in the menu to fork this screencast
to its own scrim for you to do all of
your coding in so let's take a look at
the requirements for this project like i
mentioned there will be two screens the
first one that asks them to start the
game and the second one which has all of
the questions in it your app should pull
five questions from the open trivia
database api which if you click the
green text here it will send you to that
api after the check answers button is
clicked it should tally the number of
correct answers and display it at the
bottom and as always with these projects
you should make sure that they are
styled and polished
clicking the link here on this slide
will send you to the open trivia
database which is a really fun api to
use you can click in the upper right
where it says api which will lead you to
this page and it has a fun little
generate api url button that you can
click after putting in some specifics
about the api if you want you can limit
it to certain categories difficulties
and so forth and it'll just give you a
url that when you call it from your code
will give you those trivia questions as
always i highly encourage you to share
your work click the discord icon to go
to the i built this channel in discord
or you can click the twitter icon if
you're sharing this in public this
project is probably a touch more
difficult than what we have worked on
together so don't hesitate to tap into
the scrimba community ask for help and
of course when you're finished be proud
of the work that you've done and share
it
so best of luck working on this project
and i really look forward to seeing what
you end up building
before we wrap everything up i wanted to
let you know that i've made a sort of
pseudo extension to this course that
gives you a crash course on using class
components in react as react evolves
people are trending away from using
classes in react but there's still
plenty of reasons to learn how to write
react using the es6 class syntax in this
one hour mini course i talk about why
they're important to learn and the ways
in which they're different from writing
react with function components and hooks
if you are hoping to get a job as a
react developer you will definitely want
to take this course to brush up on class
components since you're very likely to
come across existing code that is still
using them
if you're watching this video now as a
part of the scrimba front end developer
career path and you already have a
scrimba pro membership and when you move
on to the advanced react course this
crash course will be the first thing
that you go over so you won't have to go
out of your way to see this course but
for anybody else who's watching this
course as a standalone free react course
you can click the screenshot that you
see here which will take you to the
playlist for that course and it's
completely free to take
you did it you really did it it's been a
long journey but you have finally
arrived at the end of this course
you should seriously be so proud of
yourself because assuming you've
actually followed along the whole way
and done all the challenges you are well
on your way to becoming a serious react
developer i've said it before but my
learning philosophy is that the easiest
way to get good at anything is to do it
the hard way as such i've made it a
point to include a lot of projects and
hands-on work in this course let's take
a quick look back at how those projects
have progressed in each section
we started off by just working with some
static pages in react that allowed us to
discover why we care about react a bit
about the jsx syntax and how to make our
own custom components how to apply our
own styling so we can really polish our
projects and all of it collected
together gave us the ability to build
static pages
we used that knowledge to build our kind
of silly little static page about fun
facts about react and for your solo
project you built a digital business
card
in section two we moved on to learning
how we can make data driven pages in
react we discovered how to make our
custom components more reusable by
accepting props and how we can make the
data work for us by mapping over the
data and using that to create multiple
instances of our custom components using
props to pass in specific data to each
one
then in section 3 we really turned it up
to 11 because that's where we started
making fully interactive web
applications we dove deep into
understanding how to listen for events
how to save state and use state in our
components how to conditionally render
certain things on the page how to accept
user input through forms and how to
handle all side effects that might
happen using the use effect hook
then in section 4 we went all in on
practice we took some existing code with
this markdown notes app and added a
bunch of new features to it and fixed a
few bugs
then we built a dice game completely
from scratch
and most impressively in your solo
project you built a quiz app called
quizzical that accessed trivia questions
from an api and scored people based on
their answers i purposefully put these
projects in here to help drive forward
the curriculum in this course and each
one of the solo projects you did gave
you a chance to really test out your
skills unassisted to make sure that you
really internalize the topics that we
learned about this is truly a huge
accomplishment and you should be super
proud of how far you've come in fact i
think right now you should head over to
the today i did channel on the scrimba
community discord server and brag about
finishing this react course as soon as
you can in fact i made it so easy you
can click this screenshot to head
straight there
so what now well there is a ton more to
learn about react but before i jump into
the list on how you can dive even deeper
into the waters of react i'd recommend
continuing to just practice everything
that you have learned this might be a
great time to just use your imagination
and pick a project that's similar in
scope to the ones that we worked on in
this course and then just build it on
your own for example if you don't
already have your own portfolio site you
might even consider building one in
react that being said the react
ecosystem is quite large and fortunately
the community is also quite large so the
first thing i can recommend is i have my
own advanced react course on scrimba if
you're taking this react course as a
part of the scrimba front-end developer
career path well this advanced course is
what you have coming up in the next
module one of the first things i
recommend learning about is react router
this allows you to make what's called a
single page application which is in a
way the opposite of what it sounds like
it means that you can add multiple
routes to your website so that it
becomes a little more like a regular
website everything we've done so far has
just lived in essentially one little
page react router allows you to make a
multi-page website you can also learn
something called css in js my personal
favorite is a library called styled
components but there's a bunch of these
out there essentially they allow you to
put your css directly inside your
javascript so that you can co-locate the
styles with your actual code
if you want to branch out a bit more you
can start looking at next js or gatsby
these are both some really evolved and
powerful frameworks that are built on
top of react to help you build some
really robust static websites or even
full dynamic web applications
if you wanted to get deep in the nitty
gritty you could also start learning
about performance and optimization if
your code base gets more and more
complex or you're working in an existing
code base that really needs to squeeze
every ounce of optimization out of it
then jumping into this realm might help
you as a developer
and in this course we only touched on
two of the existing hooks use state and
use effect but there are a bunch more
that you can learn about as well
i'm so grateful that i've had the
opportunity to prepare and to teach this
react course my name is bob's role i've
been your instructor through this course
my username is bob's a role pretty much
everywhere online but these days i'm
mostly just active on twitter so you're
welcome to follow me there if you like
you can click the twitter icon to go to
my profile page
once again congratulations on completing
this course i'm excited to hear about
all the ways in which you're able to
apply everything that you've learned i'm
truly excited to hear from you i love
getting constructive feedback on the
course if you have any suggestions for
me i welcome them with open arms and i'm
excited to hear from you about all the
ways in which you're able to apply
everything that you've learned here