Transcripts
1. Class Trailer: Hi there folks, and
welcome to Discourse. The goal of this Reactjs
course is to present you with the needed tools and concepts to start building real
web applications. I'm Daniel and I will
be your instructor. I've been doing web development for more than 18 years now, both in large and
small organizations, and I still love it. You can read more about me
on my website, GScrafto. I've started to
learn how to code by trying to make
my own video games. This is the reason I think learning should be
fun and close to the same feeling you had as a kid when you were playing
and discovering new stuff. By the end of this course, we'll be building the
following game using VGS. It will be a rock paper
scissors game for each player, the game will pick a random sign and also
decide the winner. While building this game, we'll go through
various pictures of react best practices and also how to avoid
common pitfalls. The course also comes with this nice printable manual that you can use later
for easy reference. Following the content
of the videos here, there are over 35
full pages with code, example, resources, or diagrams, so you can get a better visual representation of
what is going on. I've put quite a lot
of work into this one, I hope it will be of help. Let's get started seeing class.
2. Before we commence: Before we start to do
some actual coding, we'd like to lay
out a few things. First of all, how
to use this course. The information in discourse is quite dense to get
the best results. My advice will be to go
through this course twice. First time, get a general
overview of the course, and the second time, do
the actual exercise. Each chapter comes with a start and end file that will make things easier to
follow the content. I recommend you to manual code as this will make things
easier to remember. In this course, I
will use VS Code and Google Chrome because there
are my main tools of choice, but you can use any other ID or browser
you are comfortable with. Also, we have a very
minimal set up. No set work needed,
no NPM modules. You can actually just view the source and
you'll get the code that is running in the
browser, required knowledge. From a real perspective, this is a beginner
friendly course. But if you don't know
anything about react, it could make sense to take my other beginner course
about react that I have here. You are expected to know
just a bit about topics such as what is the component or how a react state
variable works. Consider it as a course
that provides you with a thinking model about
how to make real apps. We'll see best practices,
we'll make bugs, and also we'll see how to
fix them. Co snippets. Personally I don't
like long courses. I think I never completed a course that was
longer than 2 hours. In order to reduce the
time of this course, I have defined a lot of code
snippets such as this one. You can see all of
them in here in the VS code folder where I have all the code snippets
that I use through the course. The reason for defining all of these code snippets is because it's quite hard
for me to speak in a foreign language and write
code in the same time. But also I want to save you the time where you are
just watching me, how I type stuff into
the code editor. With this out of the way, let's move to our first lesson
where we will use react, render, and react to root to make the scaffolding
for our application.
3. Render the app with ReactDom createRoot: Let's take a look
at what we have in the starting template
of discourse. There are these simple imports. In here we are just
importing Reactome and Babel as what we have done
in the past for January. Here we have also a
script block that is of text Babble is not
Javascript is text Babble. And the reason for this is that we'll need babble and also this import in order to be able
to write X in our A code. I have made this set up in the idea not to
overcomplicate things, not to start with MPM modules, web servers, a tools
or stuff like that. For now, we are just having this simple plain
index HTML file. Now let's write our
first react component. This react component,
it will be named app. In general, app is the entry point for
any react application. I will write here constant app. This app is a simple
function that will return something like
hello from the react app. By the way, what
you see here is x. This will be interpreted by Babble and will be translated
in simple Javascript. At this point, if I will save and refresh the page,
nothing will happen. By the way, we have made this
div with the idea of root, This one will serve as the main container
for our react Ap. Now, given the fact
that we want to insert the react Ap
inside of that dive, the first thing I'll
need to do is come here and write a new
variable named container. This container will be equal with document get
element by ID root. I will target this de. Next, I will need to
create a new root. For this, I'll write const root. This one is equal with
react create root. I will give it as a parameter, the container that I've just created in
the previous line. Finally, I will add a
new line where I will say route Render App Render
inside of this route, this app from here. If I will save and
refresh the page, we'll see that we have now this nice hello
from the Reactapp. The content that was before in the ID route was now replaced with the
content of our React, speaking of this root render. This was introduced in newer
versions of React before. It was another syntax, but this one comes with some
performance improvements. I will add in the handbook of this course the link towards
an article that points some of the updates that are introduced to root render. Cool. We have made our
first a component. Next we'll see how to create the components that are needed in order to build
the actual game.
4. Scaffolding the main components: Now that we have created
our main Act application, let's take another look at
our components architecture. This is how the game
will look at the end. As we can see here, we have three types
of components. First of all, there is
the player component. This component has
two instances, one for the red player and the
other for the blue player. There is also this results board that will show who won the game. Finally, there is
the game component that will include all of this. Let's now go and make the scaffolding for all
of these components. I will go back to
the index HTML. First thing I'll do is come here and create a game component. For this, I'll write
constant game. This one is a function,
a basic function. Like the app component, it will have the
following content. I'll write here a dip that will just return for
now this simple text. Now in the app, instead
of returning this H one, I'll return a new instance
of the game component. If we'll refresh, we'll
see now that what we have here is this content that we have declared
in the game component. But this is not enough. If I'll come back here, we'll see that inside
of the game component, there are players and
also this Resu board. Let's go and create
these two also. Next I'll create the
player component. This one will be named player. It will be a function that will return
something like this, just a with some simple text. Finally, there is also the result board component
that will be also a function. Inside of this function, I will say no results yet. Because in here in
the result board, we'll need to show
who won the game. Let's go in the game
component here, create all of that
arch of components. First of all, I will need two instances of
the type player. What I'll do here is create one instance and the second
for the other player. Next, I will also add this result board
that we have created. If we take a final look here, we'll see that we need also
this start game button. I'll come back here. Here I will just write
a simple HTML button. This one is not a, a component, it's just a simple HTML
element. I will save. And now if we will refresh, we see that we have
two player components, the button and finally
the result word. But for now, our player
components are exactly the same, they just have this
standard text inside them. In the next lesson,
we'll see how we can customize these
components using props. And also how we will teach
our components to pick a random element between
rock, paper, or scissors.
5. Adding props: Now that we have the scaffolding
of the components ready, let's take a look at
our final example. Again, you'll see that one player component is
red and the other is blue. And also they have some Ramble
symbols assigned to them. In our current status, both components are
looking exactly the same. They are just a div
with a standard text. What I want to do with you in the next two lessons
is first of all to assign parameters
to these components to know that this one is
red and the other is blue. And also in the next lesson, we'll see how to first draw some random elements
for these components. Let's start with the
component parameters. The first thing we will need
to do is to come here in the component declaration
and assign a color to them. In here, I will say that I want a color blue
for this player. Next in here, I will say
that I want a color red. This is how we send a parameter in this value to the
actual component. In order to read them, I will need here to add
a new props parameter. This is a default parameter that each function component
can receive here. What we can do is just to read the value of that
parameter that we send. So we can see here
props that color, let's say When we'll refresh, we'll see here that we have color component blue and
the other one is red. But we can go one step forward. We can take advantage of the Javaskipstructuring
statements. What I can do here
is come and add the restructuring
statement for the Colo. Instead of having
here props that colo, I can just say that now I want the colo and things will work
exactly the same as before. But we can even go one
step forward and do the whole destructuring directly in the declaration
of the function. What I want to say here is
that we'll get some object as a parameter and do a direct structuring
directly from here. If we save and we'll refresh, you'll see that
things are as before. But now the code, it's a bit more clean. Let's see in the next
lesson how we can draw some random elements
for this player card.
6. Random signs: We now have the color parameters
sent to the components. This is pretty cool because
we can use those colors to make one player component
red and the other blue. But what we have not covered yet are these random elements. By the end of the lesson, what I want to do is to be able to extract some
random elements. For now, there will
be just strings and show them in the
components as we have here. Let's go back to
our example here. I will first just add the comment to know
what we are doing here. And I will define a new
constant, main signs. This constant will be just a simple array
containing some strings. Each string will represent a possible value for the signs, rock, paper, or scissors
with this array. Now I can go back in the player component here I
will add another comment, saying that we are generating a random index to pick
some random sign. This will be a new constant
named random index. This random index will be
a mathematical function. It will return random values 0-2 With this random
index created, we can now come
and create another constant named random
L random sign. Let's name it. This random sign will be signs of random index. Now given the fact that
I have this random sign, I can come here and
replace all the name, all the content of the
player card with this array. Meaning that what comes from the color picks and this
is what we generated here. Actually, I rename
this to Random Sign. Okay, now if we refresh, you'll see that we
have the blue player picks paper while the
red player picks rock. After that I'll refresh again, refresh again, and so on. You'll see that each
time I'll refresh, a new random sign is
picked for a given player.
7. CSS styles in React: As it is now, our application
looks quite dull. Let's come and addit
some CSS styles. For this, I will need to
go and create a new file. This file will be
named Styles that CSS. Here, I'll paste the
needed CSS styles. Well, this is not a
course about CSS. You can take a look
at these declarations and you'll see a lot of them
are pretty self explanatory, like setting a background Carlo, aligning the text and so on. Now that we have
created this CSS file, let's come and link it to
our main react file here. The fact that I want to
import a new style sheet, and this one comes
from styles that CSS. Now if we refresh, we'll see that we
already started to have some basic styles inside
of our application. We have the background, the color of the
text is different, the alignment, and so on. But we don't have yet any
styles applied in here, for example, to the
player components. For this, I will need to
come and link, for example, the player class and the
container class with these dips that
we have inside of our react application for. I will need to add
a class name here. I will say that I want
a class name of player. And here in the other one, when we have the main
container for the player x, I will add a class
name of container. In normal conditions,
this will be just class equals container
or class equals player. But given the fact that class is already taken work the
reserve work in Javascript, we need to add this
class name with this. Let's come back and give fresh. We'll see now that we have these two elements on the screen and they
look quite nice. I'll go back to 100%
of the browser, but there is one thing
that is missing. Let's go and take another
look at the final example. I will open up our final design. You'll see here that
the sign flipped. This one is pointing towards the right side and
this one on the left. What we can do
here is to come in the CSS and add another rule. I will say that I want the second child of the type
player to be transformed. By the way, what I've done
here is a native CSS nesting. I will add in the handbook for this course a link where
you can read more about it. But what is nice here is that
after I've added this rule, you'll see now that this text
is now flipped basically. Let me open another file. This rule that we added here, this transform of
Scalix minus one goes and flips the
second player card. When I add a real sign there, it will be pointing
towards the other side.
8. Setting inline styles: We have some basic
styles set up, but there is still room to go. For example, we don't
have a background color for these items and also we don't have an image for the signs as rock,
paper or scissors. This is what we want
to do in this lesson. Let's start with the
background colo. If we take a look at how
things look like right now, we have this colo parameter
that comes in the component. This color parameter can be
used as the background color, because in here we
will have red or blue. This is exactly what we want to put as the
background here. For this, I'll come and use inline style in order to
define this inline style. Right here, style equals this one receives as a parameter a full
Java script object. I will want to say that the background colog needs to be exactly the value of the parameter that
we receive here. It will be background colo and it will be equal to coloque. Let's refresh now We see that we have the player cards with
the intended background colo. This inline object will become, with time more complex. One good idea is to come here and extract it as a
separate object here, our right inline style, this inline style will be
exactly what we have here. I will pass down this object directly
to the inline style. Things will look like exactly
as they looked before, but we have this
nice isolated object that we can come and add
more values to it later. Now let's talk a bit
about the images that will be put inside
of the player cards. Instead of having here
rock or scissors. We will have actual
images for this. I already prepared
some resources and I will share it with you. Now, I've just put on
my website the PNGs. I'll open up these images, you'll see that are
exactly for the rock, one for paper, and the
other for scissors. Given the fact that PNGs we can also have
transparent backgrounds. And if we take a better look
at the format of the URL, actually what we have there,
it's something like this. Okay? It's the address
of the website. But in here what we can replace this pattern with is actually
with this random sign. Because this random sign, we will have the values of
rock, paper, or scissors. Let's go and do this. I'll come and create a new constant. And this constant will be
equaled with that full URL. And after that random
sign, that PNG, it's quite nice
because I can come here now and for
the inline style, add this background image. Let's go back and let's refresh. We'll see now that we have those images placed
in our components, and indeed we have a bit
of a text left over. So I can now come and delete this as we
don't need it anymore. Let's see the final
example in action. It looks quite nice. For example, each
time I will refresh, you'll see that new signs
are drawn for each player. As a final note,
please remember that we have in the styles
here for the player card, we have all of this. We have the background repeat, the background size, the
background origin, and so on. And actually these are the
CSS rules that allow us to make these images look nice
inside of the player card. This is it. Let's move
to the next lesson. We will see how to add that nice animation when we
press the start game button.
9. The useState() hook: Now that we have the
inline styles set up, let's go and take
another look at the final version
of our example. Our game starts from
an empty state. You can see now that each
player has an empty state. No sign was yet
drawn for a player. Only when I press on
this style game button, Then the shuffling
animation will start and each player will
get a random sign. How things look like right
now is that our players, each of them start already
with a given sign. And the reason for this is that when we start
as a inline style, we'll set this background image based on the random sign that was generated out of the box. This is something
we want to change. But even more, what we want
to change here is the fact that I want the actual game to start when I
press this button. If we look at the
data flow diagram, basically what we
want to do out from here is the two parts. When we press the
Start Gate button to send an event to each
player component. Let's see how we can do this. First of all, what
we need to do is to change how
things are in here. Instead of having
this random sign generated each time the
component is rendered, we want to extract design
in a state variable. Therefore we want to
use a U state hook. In normal conditions you
will import a U state, so you'll say import
U state from react. But given the fact that we
are not using a web server, we have this very
minimal configuration. We'll need to make a
slight change in here. And I will import
the U state like so const and I will apply the destructuring
statement in Javascript to the react. But keep in mind that if you
are using a re create app, you'll have to import
it as it is right here. Now that we have the U state imported correctly,
I will come here. In the player component, I will define the
new state variable created using this U state and it will be sin and set sign. It's okay the fact that we will start with a Neal
variable because we want here to start the
player components without having
something selected. This set state variable will replace this random
sign that we have here. Even more, we can extract
everything that's in here, all the random generation, We want to extract
it in a function. We should be able to
call this function. When we press the button, I'll replace all that we have
here with this function. If you take a look, this pick random sin function just contains exactly the same
lines that we had before. Only that at the end we
set the random sign in this set sign state variable and everything is wrapped
in a nice function. Now one thing that
we'll need to figure out is how we should do so that this pick random sign function
is linked to the button. How can we do in such a way that when we press this
Start Game button, this function is called. I will leave this to
you as a homework. Try to do this before
starting the next video. I think there are multiple
ways how we can do this, but if you want as a tip, you should try to use
the user fa hook.
10. Trigger events in child components wip: How was it were you able to
find a solution for that? When we press the Start Game
button to send events to these A components so that new
random signs are selected. There are multiple ways
to fix this problem. Let's see a plan for
what we want to do. First, from the game component, we will pass down
a new parameter named start time to
the player component. Inside of the player component, we will watch the start time
via the use effect hook. When this start
time is modified, then we will call the
pick random sign method. Finally, in the game component, we will update the start time
when the button is pressed. Let's see all of this in action. First of all, I will go
in the game component. In here I will create
a new state variable. This one will be called
start time as we said. It also have this set
start time function. It will start from
the null value, given the fact that
you don't want to have any random signs picked
up at the beginning. Now that this start
time is made, I will go here in both
player components. I will send the start
time parameter. I will send it for
the first component, and after that I will send it
also to the next component. This start time parameter at one point needs
to be updated. For this, I will
create a new function. This function will be a
constant named start game. This game will look like, so it will set the
start time at the date. Now we'll pick the current
date and time of the browser, and we'll update it each time someone press the
start game button. Finally, we will use
the onclick function. When someone presses the button, we'll call the start game. Now given the fact
that we know that the player components will have this start time new parameter, I will go and
declare it here and let it in the parameters
of the component. We'll need to watch when
this start time is modified. For this, we'll need to
import the use effect hook. I'll go back here and here I
will call also the effect. Remember that if we had
like a normal webs, you'll have to
import it from here. Import it directly from react. Given that this is now created, let's go and add the use effect hook inside of the player
component inside of it. We'll do the following thing. We'll check if there
is a start time. Remember that initially
this start time is null. If we modified the start time, we'll call the pick random sign. Remember how use effect works. Effect gets as a parameter, an array of values. Each time these
values are changed, the function that's included in the use effect
gets triggered. Let's see, now this in action. I will refresh now. Initially we will not have any values inside of
the player components, but if we'll press the
start game button, we'll first have some random
elements drawn after that. More and so on. Basically
we have figure out a way so that we can start the game when
we press this button. Pretty cool. In the
next chapter I will also add that
shuffling animation when this button is pressed.
11. Animations and setInterval: Let's take one more look
at the final example. When we press the button, you'll see that we have
this animation that is running each time a
random sign is drawn. How can we implement
this in our example? Because right now we just press
the star game and we have directly the elements
drawn, but no animation. Well again, here, there are
multiple ways to do this. There is also a pure CSS
solution that we can apply. But again, we will be the solution that will
allow us to play with some mechanisms or
react and allow us to see how can
we avoid some bugs. Let's give it a shot.
What we will do here is to use this
set interval function. This is a Javaski function, is not something that
is dependent on react. Basically what this function
does is I will call it pass down a function that will be executed for each delay. Basically, let's say I want
to execute some code each 1 second I will put here 1,000 because it's
1 million seconds. And then that code
will be executed as each second when
the cycle is done, when I don't need that code
to be executed anymore, I will need to call this
clear integral function. So let's see how can we
implement this in our example. First of all, we'll need to know how many times
the animation did run. Let's take another look when we, we'll see that it goes for a while and after that it stops. This is because we set a
time of 20 animations to go. I'll need to come
here and create a new state variable
named animation counter. This animation counter,
it will start from zero. This one will track for how many times did
our animation run. And in the pick random sign, I will add the set
inteval function. We want some code to run
at 100 milliseconds, ten times per second. What that code is, is exactly this one that before was directly in
the root of the function. Now it will be moved in
the set integral function, we want to pick a new random
sign at 100 milliseconds. But what we want to do, we also want at one point for this animation
to stop running. I will come here, I will check out if the animation
counter is bigger than 20. We'll need to clear the
integral to stop the animation. And what I've
passed then down in the clear integral function
is exactly this one, the references that
I've made here. One final thing
that we need to do. It's also to increment at one point, this
animation cotter. Each time this integral runs, I will say animation conta here. We should increment it with one. Don't be tempted to
do something like this because if we
do it like this, we will end up with some bugs. Remember that the set state, when it runs on previous values, we'll need to call it like so. It will be called through a function that
will get access to the previous value and we will increment that value plus one. Okay, dock, now we'll run it. Let's press the
start game button. You'll see that we have the
animation up and running, which is pretty cool. I will reload the
page for the moment. If you will play
with this example, you'll see that there are two bugs for the next lesson
before you actually started. First of all, try to
find what are the bugs, both of them, and
give it a shot. Try to fix them. See you in the next lesson then.
12. Adding useRef() and cleanup useEffect(): We ended up the last lesson
we some bugs in our code. I left you as a homework, the idea to try to find
these bugs and fix them. First of all, let's
see what they are. There are two main
bugs in our code, and I made this image
for them to show. First of all, when we
start the animation, you'll see that this
animation runs forever. It doesn't stop after 20 runs, even if we have here a very clear condition that if an encounter is bigger than
20, then we need to stop. This is the first bug
and maybe the most important also if we
start the animation. And after that I fast forward, I press this button, you'll see that the animation
starts to become strange. It goes way too fast, that it should also,
it doesn't stop. Finally, there is
also a third bug which is the most easy to fix. You'll see that just if we go now in the image in the file, you'll see that we have
this null, that PNG, the fact that our file is trying to retrieve this
null, that PNG file. Let's start with this
low hanging fruit. Let's first at least try to fix this error that
appears in the console. The reason for this is actually this line, the background image. What we do here is
that we are trying to retrieve the image
from the JS crap site, and we have here the sign. Initially, you can see that this sign starts
with the null value. That's the reason why
we get that error, because in here we are trying to retrieve the assets, whatever. After that, that PNG, quite an easy fix
for this one will be to test if the sign exist. If the sign exists, then try to fetch the image. Otherwise, don't do anything, Just retrieve here
an empty string. Let's refresh and you'll see now that the error is not
present in the console. This was the first bug. Let's now move to the
most complex one. The fact that when we
start the animation, we don't get any errors, but the animation runs forever even if there
is this condition here. The reason why this
happens is because of this part is like the set state in react
is not synchronious. When we will try to
run this condition, this will not be updated yet. For example, if I will consolo here an encounter and I'll
refresh and start the game, you'll see that
it's forever zero. And the reason is
because he didn't get the chance to actually
do the full update. One way to fix this is to
wrap everything inside of the setanym counter function and use this previous value
as our reference. For example, I made in the
handbook for the course, I made this example. What we can do is to do in here a big wrap and put all the code inside
of the stan counter. And we'll know for sure now that the state value is updated
and has the correct value. But this is not great because actually there is the pick
rand function integral, a set state, it's
a bit too much. One other thing that we can try to do is to use references. References are great to work with alongside using
them in react. Forms are also great
in order to store values that are kept between renders but don't need to be shown
on the actual UY. What I will need to do here
is to come and replace this, any counter with an
any counter reference. Given the fact that we
want to use this work, because F is actually
a reference, I will need to import it
from the actual value of the reference is held up in the current field
of the reference. What we need to do here is
when we start the animation, is to take this counter and
say that current equals zero. After that, instead of using the set state variable, I will. Go back to the reference and say that I want to
increase it by one. Finally, in here I can just use this one instead of the
former state variable. Let's see how it goes. I'll go back refresh after that. If we press Start game. Now the animation is stopping
after 20 iterations. Let's refresh again start game. And the animation is now stopped after 20
runs, which is great. We fixed another bug. Finally, let's
tackle the last bug. I will go back in
the example now I'll start to press very fast
on the start game button. You'll see that the animation
is going way too fast, that it should, there
are two ways actually. There are multiple ways, but two main ways
how we can fix this. One way to do it is to use
another state variable and make this button disabled while the animation
runs, which is okay. But let's go in another topic, we react and that is the use
effect clean up function. Basically what it happens
when we press very fast, this button, the start time
parameter is modified. We call this random sign
function a couple of times. Actually we are making multiple intervals that run and change our sign very fast. That's the reason why the
animation acts like that. One thing that we can do is to use the clean up
function of effect. Effect has a function
that we just need to return given function like. So this function,
what I've got here, will be called each time
a new use effect runs. That's how we are
ensuring that we are cleaning up all the
effects of a previous run. Actually, what we want to do here is to clear this integral. Basically, we want to
call this also here. We should have
something like this. But you see that the actual integral is made in this function
and we need it here. One other thing
that we can do is to create a second
reference, this one, I will just copy
this function here, and I will say me
integral O in here. Instead of creating just a
local variable that will not be exposed to the
use effect scope, what I can do is to come
and pick up this reference. I will say that this one that current equals
with set integral. I will clear out here. But now I can also
clear out here. Actually, given that this
is just one line function, I can replace everything with just this one to make it
look a bit more nicer. Now let's run again the example. You'll see that each time I'm pressing now very
fast the button, but still the animation
runs as it should be. Each time I'm pressing
again the button, this one gets executed and the current interval
gets cleared. This is how we were able
to fix all our barks. Let's see in the next
lesson how we can use the A context API in order to communicate values from
one component to another.
13. Context Providers in React: Now that our application
is back free, let's move to maybe
the last step before deciding the winner of the game and completing
the application. This part regards how we
communicate between components. Let's take a look at
our final example. We have these two player
cards inside of them. Some random signs are drawn. On the other side there is
the Resualboard component, the one that we have here
that should know about what each player had selected in order to decide
who won the game. We can do this by passing down props from one
component to another, but in this case will
be a bit more tricky. We can do it, but it
will be more tricky. One other downside of this
approach is the fact that we end up doing too
much of props drilling. This is how things are called
when we are passing down too many components from
one component to another. Another way to fix this
and also play with some feature of react is
by using the context. Let's see how this looks. What we want to do is to
set up a react context. After each player has
picked a random sign, they will communicate to the context what was
the picked sign. After that, our
resulusboard component will pick up both signs
from the context. It will decide who won the game. You can think about
react context as a general data store
for the application. I will link in the
handbook for this course, a video that I made
some while ago explaining into more details
how act context work. But basically you
can imagine it like this as a general
place where we can put data that can be accessed by each component from
a given application. By the end of the two lessons, this lesson and the next one, we want to end up with a result board component
that looks like, so it knows what the
red player has picked and also it knows what the
blue player has picked. Let's see how we can translate all of this
talking into code. The first thing that
I will need to do is to create a
context for our game. This one will be named
exactly like so game context, game context equals
with create context. This create context is a
function that comes from react. If we just create a context, we cannot do too much
with it because we also need to create a
context provider Here. I will create a game
context provider that is made based on this
context that we made here. We can take this provider that we just created and pass it down to our app and wrap all the game in the
game context provider. We can read in each of
its subcomponents what we place in the game
context at this point. If I'll save the
file and refresh, you'll see that we have some
issues what happened here. The reason why the
LUI disappeared is that now we are rendering
the game context provider. And indeed we are passing
down as children. We are passing down the game, but in here in the
actual provider, we are not rendering
out those children. So we'll need to come and
add a new property name. Children. Actually, this
is a default property for any react component. Let's refresh it
and you'll see that now things look as before. Only that our game is now wrapped inside
of this provider. One cool thing that
we can do is to come and add a state
for the provider. And this state will
be passed down to all the components
of those providers. Let's see how we can do this. I will come here and add game provider state what we
need to contain in our state. If we think about it, it
will be the player signs, what did the red
player selected. Also, what did the
blue player selected? With this, I can
now come here and pass these values the player
sines and the Seta function. I will pass it down
to the provider. At this point, things
will look as before, will not have any
errors in the console, only that we can
read these values in any subcomponent of
the context provider. We'll see in the next lesson how to update these values
and how to read them.
14. The useContext() hook: At the end of the
previous lesson, we have managed to create and
set up this game context. We have wrapped our game in
this game context provider. As a reminder, let me show you what we're
trying to do here. We are trying to read the
signs that were picked up by these two player cards and put the signs in
the real context. After that, we can use in
the results board component, the signs, so that we can
decide who won the game. The aim of this
lesson is to read these elements and also set
them when they are selected. Let's start by reading the
game context in a component. I will go in the
player component. In here, I will write the following context,
context, game context. This means that we are
using another hook. We'll need to import
it from here. This hook provides access
to a given context, in our case, is the only context that we have, the game context. As a reminder, we have these two states variables
set on the context, The red and the blue
values for each player. Let me log this one. I'll log the context. Let's see if indeed we have those two elements there
while going the console. And you can see here
that we get from this consologan object and
what it returns first of all, the player signs that we
have set up and also the set function for
that state variable. This is pretty cool
because we can go in the pick random sign function
and set these two values, the red and the blue. But before going there, we can improve a bit this line. Instead of writing only that, I can use the
structuring statement. Together with the game context, I can say that I
want to retrieve the set function and
the player signs. Given the fact that we have now this set player signs method, I should come here and
call it and I will say, okay, set player signs. But now I've wrote it
in here in the if, when the final element is drawn. Now the question is, what
should I write here? And keep in mind that in here we are trying to update an element. What we are trying here to do is to update an
object in a react state. Because let's go again, back in the provider, you'll see that this one
is an actual object. The way to do this is to
use also a previous value. What we'll do here is to
spread all the elements that we have already in the object and just
overwrite what we need, in our case, override
the color of the player and the random
sign that was selected. With this in mind,
let's go back now in the Zulus board and see what
we have in the context. I will go here, I will
add these two lines. First of all, I'm extracting the player signs
from the context. After that, I add one more
level of the structuring, and this one is extracting exactly the
blue and the red values. Let me log the two. I will say blue. Let's refresh and now
let's start the game. You'll see that we started
from the null values and ended up with the paper and the rock
exactly what we have here. This is pretty cool because
now we can complete this resolute box component by showing what each
player has drawn. Basically, this part from here. I'll remove the consolo
because we don't need it. First of all, we should check
if both elements are set, in the case that one of these blue or red
elements are not set, then we should return no results yet exactly like
we have in this moment. After that, if both
elements are set, we can write this line. Let me refresh. I will
start the game initially, there are no results. And after that it
will tell me, okay, this blue player
has selected rock, this red player
has selected rock. And it's exactly what
we also have here. With this, we have covered
an example of how we can use the A
context in order to send values from one
component to another in an easy way without having to pass down
too many properties. Let's go at the
final missing piece of the puzzle and see how
we'll decide the winner. So how are we able to
write something like this? The winner is the blue
player, or the red player.
15. Decide the game winner: The final piece of
the puzzle will be to determine who won the
game and show the winner. By the way, in this lesson we'll not introduce any
new react stuff, it's just pure Javas. We'll determine the winner
in the results board. For this, I'll create
a new function. This one will be named Win. It will get us parameters, the red and the blue
values for the players. After I create this function, we'll also need to call it A in the returned x of the component. We'll use the
following algorithm. No. To determine the winner, we'll check if there is a draw, if the symbols are equal. After that, we'll
check if the red wins. If there isn't a draw and
also red did not win, it's safe to assume that
the blue player wins. Let's first check
the simple thing. In order to check
if we have a draw, we just need to check
if red equals blue. If we will, this string
checking if the red player we, it's a bit more tricky,
it will look like. So we have listed here the three main conditions
under which red will win. These are the
possible combinations that will make the
red player a winner. If we have any of
these conditions, we'll return this string. Finally, the most simple one where we will not even
need to check nothing because we already
checked if we have a red one is this one. The blue player will just return the string if this is not
true or this is not true. Let's see now all of this
in action. I'll refresh. I'll start the game,
finally, at the end, it will show me who won the
game and indeed is correct, because paper beats rock. Let's go another round. In here is the same. Rock beats scissors.
Yeah, this is it. This is how we write function
to check for the winner. By the way, if you think
this is a bit too much, I've added in the handbook also refactoring of dysfunction, it looks like so in my opinion, indeed it's a bit more
compact, has less code. But I think it's a
bit harder to read. I don't know,
whatever works for, You can pick and
it will be okay.
16. Class project: Now that we have learned
all of this new stuff, it's time to put it in action. We want to add a few new
features to our game. First of all, we want to have
a score tracker panel here. And also each player should
have their own name. And these names are editable. Let's see the final version
of the home Work in action. I'll press the Star Game
button after one game has run, you'll see that now we
have a counter here. Blue has one win and
Red has zero wins. And we can also reset
the score back to zero. And the fact that we
have added these names, I can now also come
and edit and say, okay, I want my new name to be Daniel and this
will be updated here. And instead of CPU,
I want to play, let's say against AI and also the name will
be updated there. As a general rule, please first try to complete
all of this on your own, and if it doesn't work, watch the next session
of this video. I will share with you
some tips on how to build these new features at
the end if you want, you can also check
the homework end where you can see the code that allows us
to build all of this. From this moment on,
I will share with you a few tips on how to
build these new features. So keep in mind that from
this moment forward, we have some spoilers here. Just go on this
section only if you have tried initially to
do the game on your own. First of all, I will start with this feature adding
names to the players. I think this one, it's a
bit more easy to implement. Almost all of the
changes need to be done here in the
player component. The first thing I will do here is to add a player parameter. This parameter will come
directly from the game. After that, with this
player parameter, I will make a player
name state variable. When we click on that name, I will use this Window. Window prompt is Javaski
feature, not a reacting, that allows us to build
windows like this one, where you can input
the new name, the stuff that you
have seen here. After we have read the new
value from Window prompt, we should update the state. And with this we should
complete the new feature. By the way, there is also a bonus here where we can try to extract all of this in a player name component
just including the player, this player name component. Moving now to the second
feature, the scoreboard part. This part right here. Everything should go in
here in these board. In here the
scoreboard should go. We should add as
layout A button. This can be a title or
something like that, and also a paragraph
with this text. While we add this one, we will complicate a bit the state of the
Resulusborg component. What we will need to
come and do here is to add multiple state
values for score bred, score blue, and also
a current winner or we can also add a
centralized object, we fold of the state in
just one single object. One other thing that we'll
need to do is to use the use effect hook in
order to replace this one. We have here the pick winner, given the fact that when
we'll pick the winner, we will also update the
score and the score, it's also a state variable. We'll end up in an infinite
loop of Re render. Basically, we'll need
to remove this one from here and place it in a use effect hook that
will monitor when new values for blue
and red have appeared. Okay, one last thing
that you should keep in mind is that when
you update the score, you should always update the score based on
the previous value. We should have
something like this in the state previous and
previous plus one. Finally, you can extract everything that we
have in here in a scoreboard component after you have tried on your own
to build these features, also check out the solution
and see how it went, compare one with each other. And also don't get back down
into just these features. Let your imagination run free and try to add all kinds
of features in here. But a very important thing
is to enjoy the process. Have fun and happy coding.
17. Conclusion: We have achieved a lot with our example starting
from scratch. We have built a full
functional react mini game. While we have done this, we
have also seen things such as how to bootstrap a react
project from scratch. But also how we can come and define components and we props. We have also seen how
to use the state, the react state to update
the components UY. But also very important
how we can update a state based on the
previous value of the state. Moving forward, we
have seen how to use both basic CSS styles, but how to use also
inline styles in order to make our
applications look great. We have also seen how to
use the use effect hook in order to monitor the values
and trigger updates. Also a very important
thing is how to use the clean up function
of the use effect in order to avoid bugs as a complementary to
the state variables. We have seen how to use the F in order to keep
persistent values between Re renders and also how to
set up things such as context providers in order to share data between
components and much more. I hope this course
was found for you and useful and you have
learned new stuff. Congratulations for
completing the course and thank you for your time. Remember that you can also check the principal handbook
for this course. And if you have questions, don't hesitate to
write me an e mail at Daniel Gongcrafto
moving forward. Remember from time
to time that you can also check my
website where I regularly publish
new articles in order to improve your
craft of webcoding. Wish you all the best and
keep coding friends. Bye bye.