Learn React.js in 70 Minutes: JSX & useState Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back to this bootcamp series so in our previous video we created this simple math game where if you get 10 points you win if you get three wrong answers you lose and towards the end of that video we discussed the main challenge of building an interactive experience like that with javascript the main challenge was that it felt like there's a huge disconnect between our data right the data that keeps track of how many points you have and how many mistakes you've made there's a disconnect between that and the user interface that we want to show on the screen it felt like we needed to manually babysit too many different elements on the page so in this video to address that challenge we're going to rebuild that same game but this time we're going to use the popular javascript library called react now before we jump into the action there are a few things i want to go over so first the question is why do we want to learn react i'd say there are two big reasons so reason number one is that it's super popular and super in demand so employers that are hiring web developers will like the fact that we know react okay but we don't necessarily just want to learn something because it's popular so the second reason we want to learn react is that it solves the primary challenge when building interactive experiences with javascript so we could say that react solves a technical problem for us now if you're not crystal clear on the problem that react is solving that's okay but i would recommend going to pause this video and searching for the 10 days of react day number one here on youtube so i've already made a video where i explain the problem that react is solving and why it's so useful and i strongly recommend watching that and understanding that before we actually learn react in this video okay the final thing i want to say before we jump into the action is that this video is designed to be quick so i usually focus on teaching and explaining in detail i don't usually just show and tell and move quickly but i am going to do a little bit of that in this video because i've already explained react in detail in the 10 days of react so if you do want a slower paced more explanatory process of learning react go check out that free playlist it's a 10 part playlist i'll include a link to it in the description however if you want a faster paced hands-on demo of react then this is the video for you okay having said all of that let's jump into the action and let's start learning react we're actually going to be working in codepen in this lesson because in order to work with react on our own personal computers in a real text editor like vs code we'd need to install additional tools on our computer like node.js and this lesson is not about node it's about react now don't worry we'll cover how to do that in our very next lesson but for this video codepen is perfect because it can actually convert our react code into traditional javascript code for us let me show you what i mean so if we just start a brand new pen and then over in the javascript column if you click on the little settings gear right about here we want to do two things so down here we want to add the react library so you can search here if you start searching for react we're looking for the result that is literally just the word react so here it is click on that we also want to include the react dom package so if you search for react you're looking for the one that reads react dash dom okay so we've included two libraries react and react dom that's step one step number two from this javascript settings screen is right here at the very top javascript preprocessor so this is what i was describing when i said that if we wanted to work on our local computer we would need nodejs in order to transpile our jsx or react code into traditional javascript however codepen can do it right here in the browser for us so if we just choose this we want this babel option so just choose babel we can now click close right here and we are ready to start using react now so how do we get started well over in the javascript column let's just begin by creating a function so function you can name it anything you want but you do want it to begin with a capital or uppercase letter so i'll just call it uppercase app parentheses curly brackets now inside the body of this function we want to return a bit of html well it's not actually html but visually it looks like html it's actually a syntax called jsx so we just say return and now if you just want one single line of jsx you can have that here but usually you're going to want more than one line worth of html right so we have parentheses here and now inside these parentheses we can have html or i should say jsx that spans multiple lines so for example we could have a div and then inside that div we could have a heading level one say hello and then below that we could have a paragraph the sky is blue okay now yes visually this looks like html to us but it's actually not it's something called jsx and an important rule in jsx is that you can only have one single top level element right so in this bit of jsx that we're returning i have this overall parent div but if i try to have another top level element down here this is not valid jsx so you can have as much content as you want to but you need to nest it in sort of one top level element so let me get rid of that unordered list on a related note if we don't actually need a container div here but we just want a container so that we can have multiple pieces of content instead of div you can actually just have this symbol like this this is called a react fragment so it looks like an html tag only the tag type is empty okay so we have this function that's going to return a bit of jsx now how do we actually use this so that something displays on our web page well over in our html let's give ourselves an element that we can hook on to so over in the html i'll just create a div with an id of app you could name it anything but now over here let's just render this into this empty element so down here at the bottom we would just say react uppercase r but the rest of the word lowercase react and then all uppercase dom so react dom all one word we're going to call a method that it has so dot the name of the method is render now we give this two arguments so a comma b the first argument is the name of the function or i should say the component that you want to render so we named ours uppercase app so for this first argument instead of just saying the word app we actually create sort of an html looking tag right so less than app and then forward slash greater than so this looks like a self-closing html element okay and then the second argument is the actual html element on the page that you want to render it into so in our case we would just say document.getelementbyid quotes and we give it an id of app and as soon as you type that in cool down in the preview area we see our jsx right hello the sky is blue only this simple h1 and paragraph is not what we actually want to build we want to recreate this math game from our previous lesson only this time we want to use react to build it now in order to save a ton of typing because typing in basic html is not educational whether you watched the last video or not i want you to visit this separate code pen this is a finished product code pen and you can find a link to this in the description of this video okay but once you do visit this link we can just borrow or copy and paste the code from this column right so i just want you to select everything in the html area so you can press ctrl a on windows or command a on mac just copy everything over and then over in our react code let's keep the overall react fragment but let's get rid of the h1 and the p so just like this and then just paste in our clipboard okay now right away this is not going to work so we don't see any content output down here and that's because in jsx we can't just say class equals because the word class is a reserved word in javascript instead within jsx we want this to be class name uppercase n now we don't want to have to fix that manually so let's just do a global find and replace so in codepen on windows you can press ctrl shift f on mac you can press command option f so here it asks us what do we want to replace let's just say class push enter what do you want to replace it with say class uppercase name push enter let's click this all button cool now because i already fixed this one you can see it reads class name name we don't want that so you can just fix that but now they should all read class name equals okay but even with that change in place we still see that nothing's being output so we still have a few more errors to fix here first of all let's pay attention to our input field element here so this is valid html5 code however in jsx if you have a self-closing element that doesn't have a matching closing tag you do want to include the forward slash oops let me adjust that so if it's on a single line you do need to include this forward slash here in order for it to work with jsx syntax so you can see as soon as we do that we do now see the interface down in the preview area okay one other quick change this attribute of auto complete in react or jsx we would actually want the c to be capitalized so just as we saw with class name you can see that attributes in jsx use camel case meaning we capitalize any secondary words okay at this point now that we're outputting the html and our elements have the css class names why don't we borrow the css from the finished product code pen so from that same link where we just borrowed the html let's just borrow all of the css copy that back in the code pen we're working in just paste it in in the css column cool so we at least have this now it's starting to take shape now we do not see the randomly generated math problem above the input field here because that was being created with javascript now before we actually learn how to make something interesting happen in our react code i do first want to show you how to stay organized in our react code so earlier you might have noticed that i referred to our function of app i referred to it as a component so in react the idea of a component is a super important concept essentially we can break down our interface into separate little chunks or modules or components this way we can reuse them in multiple places or we can just have them separate for organization purposes so for example instead of having our entire interface just in this one overall app component why don't we practice separating the progress bar area into its own separate component let me show you what i would do down towards the bottom of our code so after our app function but before we call reactdom.render let's just make a brand new function we can name it anything but it does need to begin with a capital letter in react and jsx a component that you yourself are creating must start with a capital letter so why don't we call it progress bar parentheses create the brackets have it return a bit of jsx let's say parentheses so we can have multiple lines of code okay now inside the parentheses let's just cut and paste the html from up here so i would just select this entire progress div down to here just cut that or copy that into your clipboard we no longer need it here in its place where that code was i'll just have a x placeholder we'll circle back to this in just a moment but then down in our progress bar function in those parentheses just paste in our clipboard okay now that that function is returning that jsx up in our overall template instead of that placeholder x we can just say progress bar so we can essentially pretend that progress bar is an html element obviously it's not it's a react component but you get the idea it's this simple to call it or include it or render it okay so at this point we know some of the jsx basics and we know how to organize our code into separate react components now that we're familiar with this i think it's time to actually bring our app to life or start worrying about the state of our game right so things like keeping track of how many points we've scored or keeping track of how many mistakes we've made and also storing the currently randomly generated math problem in memory now in react there's a very specific way that we work with our app data or the state of our app let me show you what i mean so first of all let's take the example of how many points we've scored up until this moment right how do we store our current score in memory in our previous video when we created the math game since we were just using regular javascript without react we could store that any way we wanted to so in the previous video we just had this object we could have named it anything and then we just gave it different properties when you're just using plain javascript like this it's the wild west you can do whatever you want in react there are rules and philosophies that we need to follow in react there's a very spelled out and defined way of working with our data so here's what we're going to do up at the very top of our app component even before we begin returning jsx so right above this return line at the very beginning of the body of our function let's say const and i want to start keeping track of the score so i'm going to make up variable names related to the user score let's say square brackets don't worry i will explain this confusing looking syntax in just a moment but inside the square brackets let's say score comma set score i just made these names up and then let's say equals uppercase react dot use state and that's a method so parentheses to call it and in these parentheses let's give it an initial value of zero okay now i don't expect this line of code to make any sense so let me explain what's going on here before we even get to the react specific ideas let's just cover this javascript syntax here so this is just our way of setting up multiple variables at once so on a new line you don't need to type this line in i'm just going to give you an example but it's like saying cons square brackets first second equals an array and imagine the first value was red the second value is orange third value was yellow then you could also say over here third so this is equivalent to saying const first equals red const second equals orange right cons third equals yellow it's just a syntax shortcut in javascript for destructuring an array and it lets you create multiple variables at once so the first variable name we include here will have a value of the first item in the array over here the second item the second value so on and so forth so that's really all that's going on here react has a method named use state and it's going to return an array with two items in it the first item in the array is the actual value so in this case we're giving our score an initial value of zero so that's what score is going to equal initially and then the second thing in the array is a function that lets you update this little piece of state data again in the future so that's why i named this set score this is going to be a function that react gives us and we can call it whenever we want this is a super super important concept in react the idea is that we as the developer we never directly mutate or change or assign the state data of our app we let react take care of all of that and react just gives us functions that we can call at the appropriate time so you and i are never ever going to try to dig into react's state ourselves and set it to equal something we just call this function and give it a value for now though let's not worry too much about this because we're not actually ready to modify the score in our game first we need to get the randomly generated math question to appear so for now though let's take it one step at a time let's focus on how we would use this first value so this is simply representing that piece of state or data right we just named it score so let's go use this down in our jsx so down here where it says you need 10 more points let's find that in our code here it is it's a paragraph of the class name of status we actually don't need this unnecessary span here to wrap the number we can get rid of that okay and in jsx to do something dynamic it's not dollar sign curly brackets it's just simply curly brackets okay and inside there we can just say score right that's going to pull in that variable so down here we see you need zero more points now we would actually want this to be 10 minus our score right so now you need 10 more points cool so this variable points towards our little piece of state data that's going to save that in memory and react will manage that for us we'll see why this is so important a bit later on now before we change gears and start outputting a randomly generated math problem here why don't we first set up a piece of state that keeps track of how many mistakes you've made so right below this line i would just say const square brackets and i'm just making up these names but maybe mistakes comma set mistakes equals react dot use state and give it a default or initial value of zero right when the game first starts you haven't made any mistakes yet okay and then down in our jsx in the status paragraph i'd get rid of this unnecessary wrapped span and instead just say curly brackets two minus mistakes perfect okay at this point let's focus on outputting a randomly generated math problem now actually generating and deciding on the numbers and problem has nothing to do with react that's just basic javascript so in our previous lesson if you didn't watch it that's okay but we wrote this code together from scratch so i'm in the same codepen link that we've been borrowing code from and in the javascript column well in our previous lesson we created this generate number function together and this generate problem function together if you're curious how this code is working you might want to go back and watch the previous video but you can rest assured that this has nothing to do neither of these functions have anything to do with react anyways from this code pen i want you to copy these two functions into your clipboard so it's the function named generatenumber and the function named generateproblem i'm just going to copy both those into my clipboard back in our react code pen up towards the top right below these two lines where we're setting the variables and right above the return right here i just paste in my clipboard okay now let's just use this function to generate a math problem and let's store it in state right then once we do that we can actually display it down in our user interface so up at the top here let's add another one of these lines that stores a piece of data in state so let's say const square brackets i'll make up names of current problem comma set current problem set that to equal react dot use state and now in these parentheses this is where you give it its initial value so i would just call our generate problem parentheses to actually call it right then and there okay now to test that this line is working well we know that we have this variable named current problem right and this function lets us know that it's just going to be an object with these different properties of number one number two and then an operator of either addition subtraction or multiplication so if we scroll down a bit into our jsx view we have this empty paragraph with a class of problem inside there let's just say curly brackets to do something dynamic current problem dot number one cool you can see that already gives us four and then we would want a space and then we would want the operator so curly brackets again current problem dot operator looking good and then finally we'd want one more space curly brackets current problem number two awesome at this point i think the next logical step is to work on what should happen when the user types in an answer and submits the form so let me show you how we would handle that in react instead of searching through the dom for this form element and adding an event listener instead of that we just go directly into our jsx and add an on submit handler let me show you what i mean so down in our jsx we're looking for the opening form tag and we would just give it an attribute of on submit notice the s is capitalized on submit equals and then a pair of curly brackets because we don't just want to give it a string of text we want to pass it a reference to a function now we actually could just provide an inline or arrow function here but to stay organized let's create a separate named function we can name it anything we want but just so we're on the same page why don't we call it handle submit okay now let's go actually create a function with this matching name so maybe right above our return i'll just say function handle submit parentheses credit brackets okay so when the form gets submitted the first thing we want to do is prevent the browser's default behavior we don't want to go to a new url and we don't want to submit this form data to a server anywhere we just want to stay on this exact screen so to prevent the browser's default behavior in these parentheses we'll say e this lets us access the event that just took place and then in the body of our function we can say e dot prevent default okay so now when we submit this form nothing happens perfect from here i think the next step should be to determine if what the user typed in is correct or not well actually before we worry about what the user typed in we first should figure out what the correct answer is right because our function that generates a problem it's not like it has a property named correct answer that we can just check it against so first we would want to look at the current problem in state and determine or calculate what the correct value is so let's do that first within our handle submit function right below this prevent default line i'm just going to create a variable and name it correct answer i'm not even going to set it to equal any value i'm just establishing this variable name in this scope okay now below this i'm going to say if parentheses and we actually don't need curly brackets here if you're just going to run one statement if the condition is true so we'll say if and i want to check the operator of the current problem so i'm going to say if current problem remember that's in state so we can look inside it it's an object it has a property of operator if that equals plus right if it's a string of text of just the plus symbol then i'm going to say the correct answer should equal current problem dot number one plus current problem dot number two okay if you need to pause the video and type out this line of code that's okay but essentially now i'm just going to duplicate this copy and paste it this time around i'll check to see if the operator is minus or dash then the correct answer would equal this number minus this number and then finally paste it in again this time if the operator is x now x is not how you multiply two numbers in javascript it's actually asterisk but we want to display an x to our visitor and that's what we're doing in our generate problem right it can be an x not an asterisk because maybe the average person doesn't know that asterisk is multiplication so i'm just saying if the operator equals x then the correct answer should equal this asterisk that okay now after all three of those ifs let's just alert out in an annoying pop-up the correct answer just so we can see if it's working and it makes sense so i'll say alert correct answer okay now obviously your numbers will be different than mine because it's random but i see the correct answer would be nine and if i submit my form cool i see an alert pop up with nine at this point the next step is we need to be able to compare that correct answer value with whatever the user had typed into this field now if we were using plain javascript without react we would probably just search through the dom for this input element and then grab its value however with react we never manually search through the dom like that so instead the react way of handling this situation is to pay attention anytime this field changes its value okay and then any time its value changes we're going to store that latest value in state okay and then right here when we want to compare the correct answer to whatever the user is typed in we don't need to actually go look in the dom for this element we can just grab that value that's already in state so the big concept here is that in react the single source of truth is our state or data not the web browser's dom let me show you how we can do this so down in our jsx we want to find that input field so here it is the input tag and we're just going to give it an attribute of on change and again that's an uppercase c and change but on change equals and then we don't just want to give it a string of text so curly brackets we want to give it a function now you could go create a separate named function and just include that name here but if what you're going to do is relatively simple i like to just include an arrow function here however let's first decide what we need to do here essentially we want to update a piece of state that keeps track of the current value for this field so what i would do up at the very top of our file we already know how to keep track of state so i would just create another one of these lines const square brackets why don't we call it user answer comma set user answer equals react dot use state let's give it a default value or an initial value i should say of just an empty string of text now remember earlier when we were talking about what use state returns we said that it returns an array with two values well up until this moment we've only ever used that first value in the array right that's the actual value and state this is going to be our first time using the second value which is a function which we can use to update the value and state so let's go use this set user answer function so back down in our jsx we're looking for that input element so anytime its value changes we're running this inside these curly brackets let's give it an arrow function so we'll have one parameter of e and then arrow symbol and then the body of our function well all i want to do in this function is call that set user answer function and now in these parentheses we give it the new value that we want in state so we could say pizza or unicorn but instead we want to just grab the current value that's in the input so we have this parameter of e for event that contains information about the on change event that just took place so we can just say in these parentheses here e dot target so that's the element that the event just occurred for the input and then just say dot value okay now to test that this is working back up in our handle submit function instead of alerting the correct answer let's alert whatever the user is typed into the input field so i'll just change this from correct answer to user answer right that's what we named our variable up at the very top of this file that will contain the value in state let's test it out so if i enter a value of one two three four five hit submit perfect we see that latest value in the alert at this point we're now ready to compare the correct answer to the user's answer if it's a match we can increment the score that's in state if it's not a match we can increment the number of mistakes that's in state let me show you how i would do this so back in our handle submit function let's get rid of that alert and instead i'll have one more if statement so if parentheses this time i do want curly brackets and then else curly brackets for the condition if i would say if correct answer equals and then i'm going to use a function in javascript called parse int we give it two arguments so a comma b as i said in the previous video i'm not going to lie and pretend that i fully understand from a mathematical perspective what the second argument does but i know that if you give it a value of 10 this is going to behave the way we would expect so you can give it a string of text and it will parse it as a number so for the first argument instead of a it would just be user answer okay now if this is true and it's a match inside this if block we would just want to increment the score so instead of using our score variable we would now use our set score variable and it's a function that we can call so we just give it a value and then behind the scenes react will handle the micromanagement of state we don't ever directly mutate the value ourselves so in these parentheses we could just say whatever we want the new score to be so 1 points 2 points 10 points whatever number we want now in this case we don't want to just spell out a number instead we want to increment the existing number by 1. so instead of just giving this a value you can also give it a function so why don't we use an arrow function we'll give it one parameter of prev short for previous arrow symbol and we would just want to return a value of that previous value plus one okay and then in the else block we'd want to do the same thing only we'd want to increment mistakes by one so set mistakes you could just give it a value or you can give it a function that returns a value so react will pass your function one argument and that is the previous value that was in state so we'll receive that with our parameter arrow symbol we just want to return that value plus 1. okay let's go ahead and test this out so if i get this answer wrong on purpose cool notice this number just updated in real time if i get it wrong again now it's down to zero what if i get it right cool you need nine more points instead of 10. at this point before we move forward and keep building the app i do want to take a quick timeout and explain how this is working or how react updates the screen like this what i mean is each time i get this answer wrong we see the number here updating but you and i didn't tell our interface to update right there in fact you and i only ever told our component to render this one time down at the bottom of our code right so this render line that we wrote is only ever going to run once when the page very first loads and yet our interface is still updating each time we get a wrong answer and we update our state so how is this working well this is the beauty of react so whenever our state right the data in our state whenever it changes react is going to re-run or re-execute our functional component so every time we get a question right or every time we get a question wrong we're updating those values in state so react is automatically going to call our function again however and this is the part that's actually impressive if we scroll down to our view right all of our jsx that we're returning react does not just re-render the entirety of our view that would be super slow instead react is smart enough to determine just the little tiny parts that actually need to change since the last render this means you and i get the best of both worlds we get to define our entire interface in this one conveniently centrally located place but we don't have to re-render this entire thing each time behind the scenes react is micromanaging and babysitting the dom for us and it's smart enough to only actually update so for example if we get a question wrong again it doesn't repaint and re-render the entire screen it's smart enough to only update that one little section of the web page so the best of both worlds is we get developer convenience and the web browser gets blazing fast performance between render updates big picture you and i don't need to babysit the dom we just worry about our state and the interface will automatically hence the name of the library react to our latest state okay having said all of that let's get back to work and continue building our project so if we get a question correct we don't just want the question to sit here we would want to generate a new question right or to be more specific in terms of our react setup we would want to set a new current problem in state let me show you what i mean up at the top we have this piece of state named current problem and we also have this function that react gave back to us named set current problem and remember we're giving it its initial value by just calling our generate problem function which returns the object with number one number two and operator so whenever the user gets a question correct let's just call this function and give it a new problem so down in our if else within our handle submit function down here if the correct answer matches with the user entered in addition to just updating the score so in this if block let's just add a new line and say set current problem parenthesis to call it and just give it the result of our generate problem function so parentheses to call it right then and there okay now let's test this out so if i get this question correct cool now i only need nine points but notice the question actually updated so now the correct answer would be negative one so on and so forth this is great but i'm noticing something super annoying and that is that we shouldn't need to manually backspace or delete out the old answer if you get a question right it should just automatically remove your old answer for you now if we were using plain javascript without react we would probably just search through the dom for this input and clear out its value but the question is how do we accomplish this in the world of react well the answer is we turn this into a controlled input let me show you what i mean so if we find that input in our jsx here it is let's just give it a new attribute of value and set that to equal curly brackets and then just point towards our piece of state and we named it user answer remember up at the very top of our code we give that an initial value of just an empty string so when our page first loads that's what the input is going to be set to to test this out up at the top here if we change this to hello well now when our app first renders you see hello is already pre-populated in that input let's put this back to just an empty string though the point that i'm getting at here is now we can control the value of this by changing this piece of state right that input is now controlled by the state so if we go back down to our handle submit function and in this if block for if you get the correct answer we can just say set user answer right we're calling that function that react gives us and this lets us change or update the state so in these parentheses just give it an empty string of text to put it back to that value let's test this out so if i get this right negative 4 push enter cool i get the point and the input is automatically cleared out for me so now i can just go 18 64 28 perfect now you will notice that if you don't use the enter key on your keyboard and you actually click off that field and then click the submit button it would be nice if the input was automatically focused for you so you don't have to click into it again for your next answer we can learn how to handle that in the world of react a bit later on in this lesson but for now i don't want to get sidetracked for now let's work on something a bit more fun and let's start having this progress bar fill up with green or animate with green to show you how many points you have and actually before we worry about having the progress bar always use the current score from state let's first just set it to a hard-coded value like for example let's say we have three points so in our jsx or actually in our entirely separate function remember we named it progress bar we created a separate component just for the progress bar well towards the bottom of that we see this div with a class of progress inner now the next 20 seconds have nothing to do with react this is just css but the way that we're going to control the size of the green progress bar is just by changing its transform scale x value right and then css transitions will handle the rest so now the question is though how do we modify css from within react well we can just give this progress inner div we can just give it an attribute of style and set it to equal curly brackets curly brackets is how we do something dynamic instead of just a string of text and now inside there we want to have another pair of curly brackets because we're just going to give it an object with different css properties we actually only need one property though let's say transform this is the name of a css property colon and let's give it a value of well first let's actually say back ticks so we can have a string of text and maybe do something dynamic if we need to later but let's say scale x parentheses and inside there just say 0.3 so if we check that out cool you can see it looks like we have three points so the way that scale x works we covered this in the previous video but if you give it a value of just one it's going to let the element be its default or standard size if you give it a value of 0.5 it's going to be half of its normal size so this works really well with our 10-point system you would just take whatever the current score is and divide that by 10. so to set up the math for this instead of a value of one inside these scale x parenthesis let's just say dollar sign curly brackets to do something dynamic and then just say 3 divided by 10 or any number divided by 10 and that's going to give us the fraction right the 0.3 or the 0.5 or the 0.9 that we want so now we would just want to pull this number from state whatever our score in state is will make perfect sense here there's only one problem though we separated out the progress bar to be its own separate component and it doesn't have access to the state of our app component so how are we going to handle this well let's actually go up and look at our overall app component and remember this is where we're actually calling or saying we want to render the progress bar here so this is right below the form and the status paragraph we'll check this out when we're calling this progress bar component here we can just give it attributes the technical react name is a property or a prop so we can just say sky color equals blue grass color equals green you can make up any number of different properties you want to pass into this component now we don't actually want sky color and grass color but instead why don't we make up a property name of score and set that to equal curly brackets because we don't just want a string of text we want something dynamic and now we could hard code this to the number three or the number nine but why don't we instead just say score because remember we have a variable up at the top of this app function that is always going to contain the latest score value from state right and we know that any time our score changes react is automatically going to call our app function once again for us so this will always be using the latest value so down now in our progress bar component when we're actually spelling out the jsx for that component down in the progress inner instead of three we would just want to pull in that property now to do that when we're defining this function in these parentheses we just want to include a parameter you could technically name it anything but the industry standard is to name it props short for properties okay and now we can access that down here so instead of three we can just say props dot and we named it score but remember you could have other props like sky color or grass color or any other props you want to pass into this component but we named ours score so let's test this out now so the game first starts we have zero points if i get a question right cool we have one point two points three points you get the idea at this point i think the next logical step is to add a win condition and a lose condition so that these values can't just go on infinitely so for example off camera let me answer a few more questions correctly okay so i have nine points i should only need one more point to win so if i say three and push enter the game should have just ended and the overlay should pop up and say congrats you won but we never added that bit of logic to our code anywhere so you can see the progress bar just keeps going and the same thing with the mistakes so i can sit here and just make infinite mistakes and this number just keeps climbing now there are a thousand different ways that you could implement those win and lose conditions but here's what i'm going to do so first of all when either of those conditions occurs so when your score equals 10 or when your mistakes made equals three in either of those scenarios i want the full screen overlay to appear so let me show you what i'm talking about in our jsx in the view for our overall app function below the form below the paragraph even below the progress bar we do have a div with a class of overlay now right now this paragraph with the end message is empty but inside this paragraph just as a test if i say congrats you won well we still don't see anything however if on the overall div that has a class of overlay if we give that a second class so just a space and give it a class of overlay dash dash so two dashes visible well now notice that the overlay is absolutely visible congrats c1 and the start over button so what i'm going to do is just write an if statement or really a ternary operator right here in the code so that this class of overlay dash dash visible only gets added if our when condition or lose condition is occurring so let me show you what i'm going to do let's actually get rid of the value entirely so it's just class name equals and then empty and we don't even want the quotes instead of quotes let's have curly brackets so we can do something dynamic so let's start with a string of text that says overlay and then i'm going to add on so plus and then a pair of parentheses and while we can't have a traditional if statement in our jsx in line right here we absolutely can use something called a ternary operator so how this works is you give it a condition so our condition would be if mistakes equals three or so that's two pipes so you hold down shift and press the key to the right of the curly bracket key so two of those so we're saying if this is true or if score equals 10. so if this evaluates to true then you have a question mark now we say what we want to output if that is true so for a placeholder i'll just say x then you have a colon and you say what you want to do if this is not true okay so if it's false we don't want to do anything so let's just output an empty string but if this is true instead of this x placeholder here we can just say quotes let's have a space so it doesn't run up right against the end of this word so empty space and then just overlay dash dash visible now this ternary operator has nothing to do with react this is just a part of javascript however let's test it out now so if i get questions wrong on purpose there's my first mistake second mistake if i make one more mistake should be game over cool now obviously we don't want it to say congrats you won so let's change that right now inside this paragraph here we can just set up another ternary operator so let's hollow out the paragraph i would just have a pair of curly brackets to do something dynamic for the condition i would say if score equals 10 question mark what do i want to do let's output a string of text that says congrats you won colon if it's not true what do we want to output a string of text that says sorry you lost okay let's test that out so if i get these wrong cool sorry you lost now we will want to make this start over button reset the game but before we get to that off camera let me get 10 questions right to show that that's working if you're following along in codepen and you want to do that as well you can just make a minor change up here to have codepen re-render the page for you so for example i could just set this to nine wait half a second so codepen reloads put it back to 10. cool now off camera let me get 10 questions correct okay one more question cool congrats you won and actually i'm noticing a designer css detail so before we switch gears and start working on the start over button i think the background should be blurred when this full screen overlay is appearing so to handle that here's what i would do up in our jsx within our main app component towards the very top of the jsx that we're returning we have this overall sort of container div named main ui and it contains everything except for the full screen overlay so i would just want to blur this entire div if either the win condition or lose condition has just been met so here's what i would do i'd hollow out that class get rid of the quotes say equals curly brackets quotes main dash ui after the quotes plus and then just parentheses and then include a ternary operator so if mistakes equals 3 or if score equals 10 question mark if that's true quotes add a space so the class names don't run together and just give it a class of blurred again this is not a css lesson this is a react video so we're not going to go over the css that makes this possible it's already in the css that we copied and pasted into our code pen but if it's not true so colon we don't want to do anything just output nothing an empty string okay let's test this out so if i lose on purpose cool notice how the entire background is now blurred and we have our overlay at this point let's change gears and make the start over button actually do something when you click on it so when you click on it we just want to update the state so that our score goes back down to zero our mistakes go back down to zero we empty out the input field and we generate a new problem so to get started let's go find the button in our jsx so it's down in the overlay it's a button it has a class name of reset button on the opening tag here let's just give it an attribute of on click uppercase c to start out click say equals currently brackets and then give it a function name you could include an arrow or inline function right here but we're going to need to do several things so i think we should create an organized separate function you can name it anything but i'll name it reset game okay let's go create a function with this exact name now so up above before we start returning jsx in our overall app component i would just say function reset game parentheses curly brackets let's set the score and state back down to zero so we know we have a function named set score we call it we just give it an argument of zero do the same thing for the piece of state that stores how many mistakes we've made so set mistakes put that back down to zero let's empty out the input field of whatever previous answer they entered so set user answer give it a value of just an empty string of text and finally let's generate a new problem so that's set current problem in the parentheses we would just call our generate problem function that returns an object with the properties of number one operator and number two so just generate problem oops okay let's test this out so if i lose on purpose sorry you lost and if i click on the start over button perfect off camera let me make sure it works if i win instead of lose okay one more point congrats you won start over progress bar goes back down perfect at this point let's change gears and let's work on the detail so that if you get a question wrong the problem sort of zooms and animates and fades into red to get your attention so for example if i look at the finished product and get a question wrong notice how this zooms in and turns red for a split second so let's implement that in our project so css is going to do the bulk of the work here however it's not as simple as just adding a class to this because yes that could transition it to zoom in and be read but then if you get another question wrong well we don't want the element to already have the class that makes it red and zooms in so what i'm getting at is we need to add the class to this element for a split second and then remove the class so that if you get the next question wrong again it can do it again now there are probably a hundred different ways you could set this up but here's what i would do up at the top of our code i would just create one more piece of state so i'd say const square brackets you could name it anything but i'll call it show error comma set show error set that to equal react dot use state and let's give it an initial value of false so the idea now is down in our code when we get a question right or wrong in that if else block we can just set this to be true for a split second and then set it back to false so let's go do that let me scroll down so in our handle submit function we're looking for the if else if you get the correct answer in the else block after we increment the number of mistakes we can just say set show error give it a value of true okay then let's wait maybe 401 milliseconds for that red zoom animation to complete and then we can just set it back to false once again so i would just say set out you give this two things so a comma b the second argument is how long you want to wait in milliseconds so maybe 401 milliseconds okay the first argument is just a function that you want to run let's give it an arrow function so parentheses arrow symbol and then just call set show error and put it back to false okay now all we need to do is go into our jsx and find this element that we want to animate and give it a class based on that piece of state of show error so let's go down into our jsx here it is we're looking for this p element the paragraph that has a class of problem and let's actually hollow out this class of problem and actually instead of quotes let's say curly brackets i'll say quotes problem after the quotes plus parentheses and i'll just use a ternary operator i'll say if show error if that's true then question mark i want to have a string of text begin with a space so it doesn't run into this word and say animate dash wrong so if you dig through the css that we borrowed you'll see that there's an animation associated with this class again this is not a video about css so we're not going to discuss that but then colon what do we want to do if this is not true well let's just do nothing so just an empty string okay let's test it out so if i get a question wrong perfect notice it zooms and turns red for a split second if i get another question wrong awesome and once again i lose perfect at this point let's change gears and jump back to a detail that i said we would cover earlier in the lesson and that is if you get a question right or wrong but then click off the input and instead of pushing enter on your keyboard you click the submit button well after that we would want to automatically refocus the input for you so that you don't need to manually click on to it to type again now refocusing an element like this is a bit tricky in react because in react we never manually search through the dom and there is no easy declarative way in our jsx to refocus an element however there absolutely is a way to handle this in react so let me show you what we would do first of all let's find that element in our jsx so it's this input and we just give it an attribute of ref short for reference we say ref equals curly brackets and we just make up a variable name and we're going to create this variable up at the top of our code in just a moment let's make up a name of maybe answer field okay with this in place now up the top of this function let's go create a variable with this name so up at the top here i'll just create a variable say const and this is actually not going to be a piece of state so we don't need to destructure it with the square brackets instead we can just say const answer field equals and now we're going to use react but we're not using use state we're going to look inside react and use a method it has named use ref let's give it an initial value of null or nothing so the way this works is when our code first runs obviously this line of code will be interpreted before the jsx view so first we're just creating this sort of container and we're setting its initial value to nothing but then once our jsx is parsed react will see oh that element that input it has this ref so then that's what the value will be set to it'll point towards that element so now we can imperatively control that element even though in react we usually 99 times out of 100 want to declaratively control things in our jsx so i just want to make that clear this is not our desired or perfect way of handling things you really only use this when you absolutely need to and even in the official react documentation for use ref the exact example they use is when you need to focus an element so that while there's nothing inherently wrong with use ref i would say that if you're using it a lot all over the place it probably means you're approaching things from the wrong angle maybe not necessarily but it's just something that you probably don't need to use super frequently in react anyways having said that let's go use it so let's go find our handle submit function and right after prevent default whether you get the question right or wrong let's just refocus the input field so we can just say answer field and now we actually can't just call the focus method directly on that we do need to first say current the current value of this reference and now we can treat it like a dom element so now we can call the traditional dom method of focus okay let's test it out so if i get this right but don't use enter key on my keyboard and click submit awesome it refocused the field for me if i get it wrong click off perfect at this point let's take care of one more detail before we're finished with the app and the detail is if you win or lose and then see the overlay i think it would be cool if the start over button was automatically focused so that you don't even need to use the mouse you could just use your keyboard because if that button is focused you can just press the enter key on your keyboard to simulate clicking on the button and that way you can keep playing really without ever taking your hands off the keyboard and actually if we're going to set that up we should go adjust our reset game function so that it focuses the input field for you once the game is reset so for example if we go find our reset game function let's just add a line and say answer field dot current and call focus so let's test that out now so if i lose and then click on start over i want the input field to automatically be focused perfect okay so now let's get to that detail where the start over button should be focused once the overlay appears there are a hundred different ways you could accomplish this but i'm going to give you one more tool in your react toolbox in order to accomplish this and it's a tool called use effect so let's do this up towards the top of our code maybe right below all of these state and ref lines let's just say react and then call a method of use effect now we give this two arguments so a comma b the first argument is a function that you want to run at a certain time and then the second argument controls when that function will run now by default react will run your function after each new render however if you don't want to run it after every render well that's where the second argument comes into play so we give this a list of dependencies and then react will only call our function if those dependencies have changed since the last render so for example instead of b we give it an array and let's say our dependencies would be the user's score and the mistakes they've made all right so anytime either of those things change we want to run our function so i would just say score comma mistakes okay and then the first argument is just a function that will run when these change so let's say parentheses arrow symbol curly brackets and then i would just set up an if statement to check to see if the win or lose condition has been met so i'd say if parentheses if score equals 10 or if mistakes equals three curly brackets so only if that's the case that would mean the overlay is visible so then i would want to wait maybe 331 milliseconds for the overlay to fade into view and then i would want to focus that start over button so first let's set up the delay i would just say set timeout you give that two arguments the second would be 331 milliseconds the first is just a function so let's say parentheses arrow symbol and then for now i'll just put a x placeholder but this is where we would want to imperatively focus that start over button now we've already learned how to imperatively do something to an element in react it's not something we're going to need to do very often but when you do need to do it the use ref method is the tool for the job so let's go give that button a ref so we're looking for the div with a class of overlay inside that there's a button let's say ref equals curly brackets let's name it reset button okay then up at the top of our code we can just create another reference you could even just copy and paste and borrow this code if you wanted to change the variable name to reset button okay and now in our timeout here instead of the x placeholder we would just say reset button dot current and then call the traditional dom method of focus i realized we just covered a lot of ground and we didn't really explain use effect in detail if you want to learn more about use effect and when it really makes sense to use it go watch day number 10 of the 10 days of react it's a free video series playlist i have here on youtube but anyways let's test this out so if i lose and if i don't even take my hands off the keyboard cool you can see the start over button got focused so now if i just push enter again on my keyboard perfect and that is going to bring the technical aspect of this lesson to a close that was a long video so congrats on making it to the end we did cover a lot of ground so hopefully it feels like it was worth it if you want to continue to learn more about react you can either check out the 10 days of react free playlist here on youtube or you can check out my premium react course on udemy called react for the rest of us in the course we learn all about react and we use it to build the front end for a simple social networking site having said that at this point let's talk about where we go from here so we were in codepen in this video because it can automatically transpile our jsx into something that the web browser can recognize so jsx is easy for us to work with but the web browser only understands javascript it has no idea what to do with jsx so behind the scenes codepen was automatically converting our jsx into javascript that's why we used codepen but in the real world we want to use a real text editor on our computer we don't want to be stuck in codepen however in order to transpile jsx on our computer we need to install something called nodejs and as you might have guessed that's exactly what we're going to learn how to do in our next video if you're enjoying this series so far as always i'd appreciate it if you could share it with your friends and family take care and i'll see you in the next [Music] one [Music] you
Info
Channel: LearnWebCode
Views: 17,311
Rating: 4.969512 out of 5
Keywords:
Id: 70fadMRqnBo
Channel Id: undefined
Length: 69min 17sec (4157 seconds)
Published: Mon Sep 14 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.