How to Build a Quiz App using React (for Beginners)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi in this tutorial we're going to be learning how to build quiz application using react we are going to be covering how to set up react project from scratch and along with that I'm gonna explain you all the pieces in react project structure so that you understand what it requires and how it works when it comes to the project we're gonna learn how to build react functional components how to use hooks such as use State use effect and use ref we're also gonna learn how to create intervals inside of react how to manage events we're also going to cover how to manage conditional rendering and how to render a list in react but this is just tip of the iceberg so if you react.js beginner get yourself comfortable and let's start go with slova Okay cool so first thing first uh I want to open up a git bash here on my desktop so git bash and let me zoom in a little bit so you can see what I'm typing I'm gonna create new project and I'm using wheat I see there is a lot of excitement about this lately and even angular included in there uh it's basically a building tool and the good thing about wheat is it's uh fast it's simple you don't have to worry about almost any configuration and it's ideal for beginners so that's why I like to use it so in order to use uh Delete you need to have npm installadium on your machine I'm using uh npm Version 9 but you should be using version 7 plus in order to write exactly the same commands as I'm writing here what template we want so for our case we want to be react so npm create read at latest name of your application here and then dash dash template and now we want to provide what is the template so I want to provide react like so and now hit enter so you don't have to worry about installation and anything so you can see it takes just a couple of seconds now we should open up visual studio code or what is your code editor so just open up that folder which we created so it's named my quiz select folder and let me just zoom in so now I can open up a thermal inside of the visual studio code and what I want to do I I want to add SAS so I want to support for SAS so just type in npm add Dash D for Dev and let's add SAS full development dependencies basically and let's wait for a couple of seconds to install okay let me clear console okay let me install all the dependencies so npmi for install and let's run this bad boy so you just need to type in npm run Dev it should start a development server for you and there you go it's just like 500 milliseconds it's very fast okay let me import it here and let me just bring up this window as well we're gonna need it just in a second so and with that we have created our application so let me shrink it down so here let's first see what we got with this with uh building tool so let me shrink down this terminal first we have generated our folder here and obviously we installed all the packages that we need for our application and if you go to the package.json file we can see that we only have react and react on only two packages that's that's amazing and also in the dev dependencies so these are the dependencies that are used only during the development so we have types for react and we have vid react plugin and we have the SAS for compiling the SAS code and obviously we wanted to install a bit for itself so there is not a lot of packages inside of this project and that is the reason why this is very fast and uh not not only that but you know among other things and is as you can see here we have among the scripts three commands that we can run so npm run Dev starts your development server you have npm run build which builds your project and later we're going to build a project and upload that to provolone amplify uh I'll I'll check it later and you can preview as well and apart from that we have this public folder inside of this public folder you usually put stuff which are not included inside of your Javascript file like robot.txt file so this the files which are not including inside of your uh JavaScript code are usually placed here and then we have this git ignore obviously this is the file which is ignoring all these directories so it may be something like vs code you can see here odd node module so you don't want to commit that right and then you have this index HTML file so inside of this file we're just including the main jsx file and we're going to get there just in a second it is it is in the source folder and we have this root div folder so this is the main folder of every react application why that is the case because the entire application gets injected inside of this root folder so inside of this Source folder which is the main folder obviously we have this assets folder inside of this assets folder you place all your all of your assets so like images uh I don't know CS not CSS files CSS files are here but images uh icons you know things like that fonts obviously and that that is for it here we have app.css file this file is a styling file or a only component which is the app component I can remove all the CSS code because we are not gonna apply any CSS code for our app component uh at the moment the app component is the only component inside of our application so we can remove actually all of this code because we're gonna create our own code so I can remove all of these boilerplate code here like that's right hello as a placeholder so let's remove the logo react logo new state hook all of this and we even don't need this CSS file so just to clean up things okay here we have this index.css file which is basically I can also remove everything from there this is like a global CSS files uh where you apply some styles to your entire application so share CSS and then we have this main GSX file and this is the file where we are importing that CSS file we are importing our app component and what we are doing here as you can see here we are importing react Dom and we are creating our application using Create root and then we are selecting the root div so this is the div inside of our index file here relative and what we're doing is we're just injective or rendering this component and we are applying this strict mode I mean strict mode is something that helps you provide you with more uh more it's more strict and gives you more error so you're it's more stricter but and also what I don't like about strip mode is that it forces your application to re-render twice so I usually like to remove that this is not recommended obviously you want to to run it in strict mode but for this workshop I'll just remove it and let me check our check our browser to see what we have now so basically we just have this hello and nothing else oh that's enough for now okay so let me close this open up the visual studio code and let's create our first component so let's click here on create new file and let's name this component as quiz Dot jsx now we're going to create a very simple functional component so just type in const with equals two and it's going to be a very simple functional component so and we want to export it on the bottom export default quits like so so we are exporting this uh component as default so what what this basically means is if you're importing this component in let's say in app.jsx file so you would import it like this import s from quiz but if you are not to export it as default so if we are like exported normally that's export const quiz right then we would need to import it from object because uh you can export different things you can export constant multiple things from one file and in that case you would need to import it from object as a property of that object so but if you exported as default it means that this is the default export of this file that is what it means here okay so here we have this question and every functional component needs to have a return statement so that that's something that we need to to provide in any case so let's just say hello hello from quiz quiz let's save this component and now let's just include it inside of our app component here we already imported it here oh let's just place it in our jsx code let's save it and let's see if we have any errors or anything it works without any issues so in order to make our application easier I hard-coded all the questions that we have in some future workshops we're gonna have uh probably a back end where we're going to create new questions store that maybe in a Firebase or some other databases and but for now we're just going to use hard-coded questions so in order to get these questions you need to go to this URL so github.com anyway if you're watching on YouTube as a recording it's going to be in the description okay so what we need to do is we need to go and basically copy this this entire object and what this basically is is set of questions so it's array of objects and inside of this array we have a question which is usually obviously the main question of that object and then we have the choices and we have the which is the type of the question and this is going to be very important later on when we when you create a different type of questions but for now we only have multiple choice questions and then we have the correct answer for every single question and we just have five questions that's it so copy that head over to our app and let's create a new file here inside of our source folder and let's name it cons uh constants like so and make it as a Javascript file and let's just paste all these questions so now what we want to do is we actually want to go inside of our app.jsx file instead of our app component and we want to pass all the questions there so you may want to you know we want to create application or actually component which can be used on different places in the application and we may want to send or send or fetch different questions so this is why we are passing this as a property so in order to add new properties just type in questions questions and then let's first import the questions from this file so let's import and again this is not a defaulty import so actually export so that's why we need to import it in this way so instead of the curly braces so we are basically restructuring it so let's name the object as just quiz from constant and now we can pass in the questions from this object here Dot and let's pass in the questions that we have so what we are doing is we are basically passing the array of these questions here okay I can close that now I can close the app just as well I'm gonna close this app the CSS file because we're not going to use it at all okay so inside of our quiz component now we're getting the questions so you can access them like this okay and what we're going to do here first I want to create a container so let me remove this yellow from quiz I want to create a container actually let me open up parenthesis and inside of these parenthesis let's create a new div so and why I want to create a reactive instead of uh I mean they have instead of react fragments is because I want to add a class name so I mean you can even add a class name to reactive but react fragment but yeah this is easier way so class name let's set it as a quiz container okay and now let's head over to index.css and let's add some uh some basic uh CSS rules so let's first establish what colors that we are going to have on our application so let's set the primary one to be to be blue color and this is going to be actually we need to rename because we want to use this as here so let's just rename this file to CSS like so okay and now let's add on 50 80 okay so this is this blue color it's going to be our primary color then we want to add accent color and it's going to be something like orangey so D 0 8 6 or two so then you want to add a color for the background so let's name this variable as BG and it's just going to be white color so FF FF like so now we want to add EG Dash accent okay so background accent color it's going to be e 7 E7 e 8 E9 right is going to be this light gray color then we're going to have disabled disabled color and it's going to be nine C Knight c9c it's like darker gray and at the end we're going to have foreground or this is used for text obviously foreground and for foreground we're gonna have two B two six 4B yeah this dark color obviously for text and now let's add some styles to our quiz container so okay let me just check our application to see if we have any issues okay we have okay so we have one issue and this is because you are importing the index CSS file in our main Json the jsx component and we don't have that so inside of our main jsx we need to import the SAS file which we created let's save it and now we are live again so just to check the console if you have any errors there it works as expected so that's fine but we don't have any text because we removed everything from our file here okay so let me open up the visual studio code again let me close this file and we defined all the styles that we have now let's style this quiz container so let me copy this class so I usually like to copy classes because uh that way I you know remove the remove the possibility of making the mistake with classes so here first I want to add a font family uh mono space now I want to add some background and I want to make like a linear background so with the gradient so let's add a background it's a linear gradient and what I want to add is first zero degrees so this is on degrees which you want this basically the angle right you want your gradient to to go so I want to set the first primary color primary and then I'm going to set 0.0.3 percent this is basically how strong the gradient is and I want to gradient two so we need two colors and the second one should be accent this one say let's see what we get here but we actually don't have anything inside of our primary container so we cannot see it yet okay so let's add the color or container to be foreground so this is the color of our text and then I want to display it as Flex I want to Center everything inside of our content so Center display contents the center and I want to set the margin to centify this okay so much zero Auto because I want it to be in the center and let's add some padding to this container so zero on the top and the bottom and we want to add some padding on the left hand side right 30 pixels inside of this container we're gonna add some questions obviously and the answers and let's set height to be 100 window height okay viewport height actually okay and there you go this is our beautiful background here that we have looks nice okay uh yeah but I see that actually there's there's this uh this padding on the background which I actually don't like so probably we should add a padding to the actual quiz container and we can apply this background color to the body itself so let me fix that so let's instead of the quiz container let's add these styles to the body container here so we can set the fun family foreground here the body itself and like so let's copy over to the body itself okay like so and now I want to set the quiz container to have the last width so there you go this looks much better here okay so let's continue let's actually get back to quiz and let's pop in some content inside of our quiz container here okay so first thing which I want to create on the top of the quiz is the number of questions that we have and the land so basically where we are at uh in the current quiz so be the current question what is the current active question so let's add two spawns actually let's add first react fragment here and let's add a first span okay and the first plan is going to be to active questions so let's add a class name now let's name this one as active Dash question Dash number and here we're gonna access so we now can access uh actually we can create a new variable and we can call this variable as like current questions so let's import the usage hook which we are going to use for handling the state of our functional components so let's import use statehook if you're not familiar you said hook it's basically a function which helps you to manage the state of your functional component previously we were able only to to make dummy functional components but with you state you're able to create variables and update their state so how do you how do you do that is by just calling you stay hook you provide uh you provide the initial value when you initialize the hook and then this function returns an array and this array contains contains two things so the first first thing which contains this array is the name of the variable uh which you want to create so let's name this one as current question and the second thing is the updating function so using this function you can update this variable here uh okay so let's call this one else Set current question and this is the naming convention that you usually want to follow so you create a variable name and then you just append the set on it so this is how you usually do it okay so the current question is going to be zero obviously so we want to start with zero so and here we want to say now we can include the current question and we want to add because zero is something which is not user for user friendly so let's just add one on it so it's like current question is the first question now let's copy paste this line and the second thing which we want to do is we want to display the total questions that we have so here let's name this class as total Dash questions and here uh we may want to use the question length and how we may find that is using these questions object that we are getting from our app file here so what we can do here is let's create a constant and let's destructure the object that we are getting from the questions here here so what we want to access is the current question so for us is because questions is the array of questions and we want to access the current question here obviously and okay let's see cannot be declare yeah okay because we are not uh we haven't created uh variables we haven't been structured this object yet so what we want to get from from the correct question is we want to get a question what is the current question we want to get the choices and you have to get a correct answer so correct answer so we are pulling these properties from the questions so if I go to constant you can see from question we have a question we have choices we have the correct answer so this is what we are pulling in here okay so I can call close this constants Here and Now what we can do uh is we can use the question we can usually in order to display the total questions we can actually just use the questions dot length that's it so now if I save Let me refresh and here we get K 1 through 67 Okay so then you see actually we need to add this or actually we took a question not the question so this is the the amount of characters that we have inside of our questions so make sure to this is the multiple this is the question and also what I want to add is I want to add a forward slash here you can add it here so to know what is the active and what is the current uh state of the question so let me open again okay so we are on the first question and we have five questions so yeah this looks correct okay let's continue so now what I can do is I can apply some styles uh to these questions so it's nice and formatted so the quiz container first what I want to do is I want to set the maximum width of this container and make it in the center so let's set the width of this container to be 500 pixels let's set the background to be the variable which we created at the beginning and it's going to be background okay so background BG then let's set some border radius obviously you don't want to have boxes without the Border radius so let's set the border is to be four pixels now let's add some margin on top and let's set it to be four pixels as well or actually let's let's make it much much uh more decent from the top of our screen so margin top 100 pixels uh let's send some padding so let's add padding 30 pixels and 60 pixels on left and on the right so on top and the bottom 30 pixels Left Right 60 pixels now let's set the Box sizing to be a border box because we don't want this pattern to reduce the size of or increase the size of our previous container so let me say let's see do we get our container okay there you go so we have this container nice here displayed okay so let me get back actually let me reduce the zoom a little bit uh okay to 200 pixels so it's not too large yeah I'm trying to make it larger so you guys that are watching on your phones can see it as well so now what we want to style is our active questions so let me copy this class again again I like to copy paste the classes because uh I cannot miss you know I cannot uh misspell the name of the classes what we can do as well we can put it inside of our quiz container because we are using SAS so we can Nest our CSS rules so what I want to do here is let's add the font size to 32 pixels let's make it a little bit Bolder so let's set font weight to 500. and let's set the color to primary so we set blue color here okay now let's save this and let me go and take total questions as well here and let's test it below the active crash here and I want to set the font size to be a little bit smaller so let's set font size 16 pixels can't wait to be same to 500 so a little bit Bolder and let's set color so great so let's use the disabled color which we defined on top here like so now let's see our colors okay beautiful this is something that which I wanted yep so that's that's it okay so let's continue and billing hopefully you have time to follow along what I'm doing here so yeah then below below this I want to create a title and basically here we want to show the tracks of our question so let's just through the question here so here we are accessing the question which we destructured from our questions array so this is going to be dynamic so how when we change the current question when we go to one two three four this is going to be different because we are re-rendering a quiz component on every single uh State change and this question text is going to be different so let's see what is the question text on the first one so if you go and head over so this is these are basically all react questions so I can even reduce because it's a little bit too too big so which of the following is used in realjust increase performance so this is the first first question that we have okay nice and now let's apply some styles to our to our title here so what we can do is below here we can Target H2 and let's set the font size font size to 20 pixels and let's uh again font weight to be 500 pixels or not because 500 because this is not defined in pixels and we want to set the margin to zero so yeah to reset the margin of the h2 tag body heading yeah like this beautiful okay let me get back together and let's continue with our coding So Below of our question we want to render the the answers so actually the choices which you can make so in order to do that so we need to create an ordered list and now we need to go and look to the choices that we have so how we do that in react is we just call the array and then we execute if you're familiar obviously with JavaScript use the map function to reiterate through the array and return back new a new array and that's exactly what we are doing here instead of the Ura we're just going to return uh new elements so this is what we're doing in in react so inside of the map we can access first the actual answer or the choice however you want to call it and then we want to access the index current index of the iteration and then what we want to return back is we want to return the LI or List item here instead of this list item so the only thing which is absolutely requires to to create when you're when you're rendering items inside of the react is the key because using this key react is able to identify and uh differentiate we try them in the the arraylist is being changed so it only updates that item and it's not re-rendering the entire list so the key always needs to be unique and let's set the key to be to answer so because we have every single answer or the choice is different so we can use the key for that purpose then what we want to do is we want to create on quick event because once we click on Li we want to perform some action obviously so we add on Quick Command this is event handler obviously and we want to execute a function so we can just use this file Arrow function and we want to pass in on basically we're going to create a new function just in a second and let's name it on answer an answer and what you want to pass in we want to pass the answer which we clicked on and we want to pass an index and let's create this function here that's above so let's create a new function and let's name it one answer click this function creates or actually receives to properties the first one is the answer or the choice let's put it here and the second one is the index if I may spell it correctly and the second one is the index so we are setting these parameters from here okay so what we want to do here is basically we want to create a new variable and using that variable we're gonna set the answer index so we need another variable and we can use again use statehook so let's create a new variable and again you said hook and for the initial State let's set it to null because when we render our application uh we haven't selected any questions yet so the first initial state is now and then we want to create a variable and the function to updating that variable let's name it as answer index and the function again you usually you adjust the variable and you add a set on it and make sure that it's camel case like the set answer index now what we can do when somebody clicks on the answer we can save that index so and how we do that is but just by using this function here so we are updating this uh this variable here so that said the index of the answer to be this index which we got from the map here and then we want to check if the answer which we selected is the correct answer so how we do that is we just check if the answer is equal to the correct answer and we get the correct answer again from the constants here and here for every question you have a set of choices and we have the correct answer and for the first one we can see what are the answers obviously and the for the first one is virtual Dom so it's going to compare if the choice is equal to the correct answer I mean you could make this to compare the indexes as well if your choices have indexes and correct answer but for this uh for this use case we're just using the strings so I mean that's not ideal but it works okay if answer is the correct answer if it is we want to set uh we want to set the answer to be true so we again need another variable so let's just copy paste this line because we're going to use usage again and let's set the initial value to be just empty as well now let's say or we can even set it to be empty string whatever we want and let's name this variable as answer and we're going to set the updated function to be set answer like so and now what we can do is if the answer is correct we can use the set answer I mean it would be more appropriate to be null okay and then we set the answer to true otherwise we want to set it to false else set the answer to be false so we want to Mark if the answer is correct or not so now this answer is a variable which holds the actual state of of our answer so now we can add different Dynamic classes to our list item so here what we can do we can add a class name any service class name we're going to check if the answer is correct or not so if the answer index here we're actually checking if the item is selected or not and depending on that we're gonna display different styles so if the answer index is equal to index if it is this means that this is selected answer so we're going to give it a class selected selected Dash answer otherwise you're not going to display or you're not going to render anything any classes to it so like so and don't forget that we need to render the choice inside of the lease items so and we name that as the answer here and let's say this and let's see what we have inside our array so as you can see we have unordered list with all the choices but we cannot do anything for now as you can see let's first apply some styles to it so let's head over to our index.scss file here and let's apply some stats so first below our H2 let's target the unordered list to our selected answer so first let's add some styles to our note list so let's add margin Dash drop which is 20 pixels let's add some margin to the left side and let's uh add minus 40 pixels because we have uh some margin on the left side I just want to shift it back so like so and then let's target the list items Target I think okay so let's add the text decoration to be none so we don't want anything to take the correction let's remove the bullet point so it starts at the none you want to set the color to be foreground like so let's set the font size to be 16 pixels uh let's set the background to be to BG like so let's add a little bit of border so it's nice and rounded so border let's say 1px solid and let's add the disabled color so this is like a gray color obviously now let's add about radios let's add a 16 pixel board radius and let's add a padding of let's say 11 pixels like so let's add a margin top to 15 pixels and let's have a cursor point so it looks like it's a button now obviously cursor pointer like so okay save it let's save a quiz okay now let's see how our buttons looks like now okay much much better cool okay it's very nice uh and now when we click on a button we should get a new class so Let's see we get a selected answer class and now we should add uh different styles to to that to that list element so let's add inside of the uh or actually we can we can add it below this Li atom so we named it as let me see what is the name of the class selected answer so you want to apply different rules to it okay so select answer we just want to change the background to it so let's set the background to be primary and let's add a different border so let's set border one PX cell solid and let's add accent color so it's more it pops up more and let's add the color to be BG like so so let's save this and let's preview again and there you go so this looks like you know correct so yeah so now we're able to select the color and we get the visual representation of it so I can close this yeah cool okay let's continue so we want to add below that we want to add a button okay so let's add below this another list let's add a div so this is going to be like a footer for our container so let's add a class name here and set a class name and it's going to be footer and instead of this footer let's add a button so this is going to be like a button for next and finish so okay instead of this button we're just gonna check uh if the current question is equal to the questions.lan so basically it means if you are at the end okay question length minus one if we are then we want to display finish this is just a basic ternary operator if we are at the end so if the current question is the question minus length length minus one we want to display finish otherwise we want to display next okay like so and then we want to add a new own click event here and we're just going to give a new function that we're going to create and also what we want to do is we want to set disable state okay let me close that so disable and it's disabled if there is no answers so if we haven't set anything so if answer index is equal to null so if we haven't selected anything so and the initial state of the answer index is null here and now for for the actual function let's create a new function let's call it on click next yeah so let's create it here because new function like so and actually I can remove these logs here we don't need it because we proved that our function works okay so let me just save and see how our button looks like and okay looks it looks decent okay we need to apply some styles to it but yeah if I refresh it should be disabled as you can see so you cannot click it then when you click on it it's enabled and now you can click on it okay so let's apply some styles to it so let's go to index.css and that's below this selected answer let's add some stuff so okay inside of the quiz container make sure to you know to have the correct order of the rule so let's first add some size to the footer I think we named it for let me see yeah footer and first I want to set it as a flex because I want to align our button on the right side so let's set the justify content to flex send to make our button to go on the right side here now let's add some styles to our button we can place it inside of or outside of our footer because we're going to have another Button as well so actually we're not this is the only button that we have so we can enter the footer let's leave it outside I just don't know where to wait so it doesn't matter it's inside of the container so let's add the background I want this to have the similar background as we have on the on the actual body so let me copy this here that it has very unique so your degree is primary and this is the the create the actual gradient that we apply and the second color is the accent color and let's add some border radius or a button so let's add nine pixels like so let's add a font size to 18 pixels let's add a color to like PG color let's add some padding so it's a little bit larger so 10 pixels on bottom and top and we want 42 pixels on the left and the right side so let's remove these that terrible outline so let's add none so let's remove the border so let's support the nut as well let's add some margin separation from the question so margin top 15 pixels like so and what I want to add as well is I want to we can also either add a cursor pointer and what we can do is we want to Target the disable state so disabled and when it's disabled let's set the background to be VG accent and let's add the color to be disabled and let's add the cursor as well to not allowed so demonstrate that you're not allowed to click on it so let's save yeah let's see how it looks now okay so if I refresh I can zoom out a little bit so you can see you cannot click on it and you visually see that you're not able to click on it what we're going to do here is we want to handle this on click next so what happens once we select the answer here we want to click on next and something should happen right so you want to check if this is the correct answer or not if it is we want to store some points so we want to at the end of this question already we want to show you how many points you have uh you made so and then to to show your score and if you if you actually if you want to retake this course again or questionary not course so let's do that inside of this on click next here okay so here we want to first set to reset the answer here because we clicked on next and we want to prepare for the next next step so let's set it for now here and now we want to update the answer the actual answer so we can use the set answer or actually actually we need another another variable and we can call that one as result so let's name it as a result and we want to be able to update the this function so let's click set result and this function is going to use use it again and we want to Define the initial State uh to this these variables so we can Define this initial State inside of our constant here so here let's create a new object because we're going to reset State at the end so that's why we can reuse this this definition so export const and let's call it result initial state like so so what we want to set here we want to set the score so initial state of the score is going to be zero correct answers is going to be obviously zero and wrong answers maybe zero as well so yeah now we can import this object here so we can use it as the initial State here and let me import this object from constant here pixel so this is the initial state that we have here for the result and now what we want to do is we want to update that state depending on the actual uh on the actual answer so if the answer because here we are setting the answer to be true or false when we are clicking on the item and here we want to check so you want to set result use this function to update the actual result here set result so here we get the previous value of our result inside of this set State and here we're gonna check if the answer is correct if the answer is correct we just want to uh we basically want to return back a new a new answer so we can remove this early brackets because we want to return this and update our current result so what we want to create is we want to create new object and we want to de-structure what was in the previous object here and let me just see you want to destructure it and what we want to update we want to update if it's correct we want to update the score to increase it so let's update the score so we take the previous score and we increase it by let's say that we the score value is five or every single answer and we want to update the number of correct answers so what we do is we take the previous correct answers and we just increase them by one that's what we want to do here but if the user has answered incorrectly and again we want to destructure our previous value so we are returning back a new object we are destructuring the previous values and we said the wrong answer we're not increasing the the points we could decrease on some questionaries you have to decrease if you if you said the wrong answer but we're not going to do that we're just going to uh we're just gonna decrease the correct answers so we're actually going to use the wrong answers and we're gonna increase the previous wrong answers and we're going to increase that so you're not actually going to decrease the correct answers but we're going to increase the wrong answers yeah that's what we're going to do yeah like so and what we're gonna do here so we want to check the set the once we click on the next we want to update the score and then we want to move over to the next question right so here we're going to after the set result we're gonna check we have the current question we want to check if this is like the last question right so if the current question it's not it's not on the last question how we check that is we just take the questions dot length minus one minus one so if you are not on the last question you can just move to the next one so let's set the current question so you are using this Set current question function to update the current function function of variables so set a current question to be to be current question plus one or we can even use like previous value and just set the previous Value Plus one we can do that as well like this like so otherwise if it's not we want to uh set the current question to zero so if you reach the end we want to reset so set the current question be zero like so and now what we want to do is we need to create uh another function or actually another variable uh and we want to this variable to tell us whether we want to show the result or not so let's create another one so let's create a const and let's name it else let's name it as a show result yeah show result and I'll get a function again set show result and the initial value is going to be also and using this function we're going to toggle uh the X what we render on our page so when we get to the end here we want to set our result to be seen so set show result to true we want to show the result here and now what we can do is we can create a new new section here inside of the quiz container and we want to check we can open up the expression and we want to check if if show result is false we want to render what we already have obviously otherwise we want to render the new section that we're going to create just in a second here that's it's going to be adjust div okay and let me take this react fragments and let me put it inside of here foreign like so and instead of this still we're just going to show the results so let's name this div let's add a class name and it's going to be result and here we're gonna have H3 heading and it's gonna just say result and we're gonna display all the results that we have so let me say this and let's try uh if it works correctly until now so what we have done is we click on on one of the items and click on the next and we get redirected to the next question and that works correctly so we are able to click on the questions and let I'm just randomly selecting questions and when we get to the FI for the fifth one so we're on the last one we get the text finish when you click on it so we should get a result yes we get the resultive back so now we we need to display all the scores and all the information okay so let's do that so inside of this result what you want to score uh we want to show the score basically so let's add the first paragraph and let's say uh total questions and we had like a span and we just say questions but length so here we just display what is the length of the questions let's copy paste this line as well here so let me copy paste a couple times for for the second one let's say total score and we can access that from the result as you may uh remember we updated the result here so we now have this score correct answers and wrong answers so let's just display them so in the total questions okay here's the total score and we just access the result and score then we have the total answers actually correct answers correct answers and we just go to result Dot correct answers let me copy this line again we have wrong answers and then we just take these wrong answers parameter here and let's try that out and actually why below here let's add a button so we want to add another chance to whoever is taking the course or questions sorry again and let's just say try again like so now let's head over to our and there you go so here we have the result we have total five questions I got 15 randomly by answering randomly and we got three correct answers so three times five is fifteen and we have two wrong answers and if you click try again nothing's happened so we need to go that so let's create a new on click event and let's create new function let's call it on try again here property let's create a new function here and all we want to do here is we want to reset our state back to null so so let's set set result to be to initial result so we're going to use that object that we imported so use the result initial state yeah so we want to set result initial State and we want to set the show answer set so result to alt like so and now when we click on it you should set results to initially to zeros and set your result to false and we already set here if we get uh to the last question here we want to set the current question to be zero so we have resetting here as well so let's add some CSS as well to it let's see what we can apply so we can Center everything all the tags that we have are in the middle so let's target the result I think that we name it result let me just see result yes and let's text align it to Center like so let's add some styles to our HDR heading uh it's H3 yes for the result let's say we want to be font size to be 24 pixels let's set the letter spacing to be 1.4 pixels and let's align it as well of excellent Center yes like so and then let's add some styles to our paragraphs so let's add the font size to be 16 pixels let's set the font weight to be a little bit Bolder to 500 and let's start the spans that we have inside it so let's set the color to be primary so you want to distinguish a little bit uh the actual values that we have inside of the paragraph and let's add the font size to be 22 pixels we're basically almost at the end so you can see here we have applied some primary color to to our spans or actual scores we have we made it in the center and if you click try again you should reset the state but actually it's not so let me just recheck it again so on click we have a typo here so it should be on click like so let me save now let's try again and there you go so let me just refresh and let's start over again so this should basically complete our tutorial but let's just see which of the following is used uh in react just to increase the performance and that's virtual Dom so let's click next what is react.js it's a user interface framework okay identify the one which is used to pass the data components from outside that's props in which language is real just written the JavaScript and what is bevel it's JavaScript compiler okay and we got the correct answer 25 and total questions is 5 total score is 25 now let's try to answer all them wrongly so let's say for the first one this none of the above set state Python and none of the above and there you go so it says total questions five total score zero correct answer zero and wrong answers five so how we can build our project is very easily so we just let me just clear the console we just run npm run build and we had to build uh this project for us so we get this new disk folder created and this is the folder which we can uh upload to the to the server that we want you know so what we can do is we can go to uh let's say netflixy.com you need to log in here obviously you need to have an account I have signed up already and what you can do is you can add a new site uh deploy you can click on deploy manually and all you need to do is here click on the upload folder we can go to desktop and this is the quiz app that we created and click on this folder so upload that folder let's upload it wait for a couple of seconds it's uploading it should be very fast because this is very lightweight component and you get new file if you click on it new URL we get our component live up and running so the first thing that I want to do is let's head over to the source folder and now as you can see we have two components we have this app component which is the main component and we have this quiz component so what I want to do is I want to add a structure to our application so once we start adding new features uh it's built up for scaling right and we can actually start our application so let's run npm run Dev which is the command for starting our application using beats billing tools so we can just click here and let me bring it here so I can actually close the GitHub window and this is the application which we built on previous sessions so we can even put it inside of the same window because this is not a wide application at all so so we can see it likely why while we are coding here okay so like I said let's build a new folder inside of this Source folder and let's name this one this is the usual naming convention so let's name it that as components so inside of these components uh folder we're gonna move in this quiz component so let's move it and actually we're not going to update or actually we can update it here but what I want to do is for every single component that we create I want to create a separate folder so let's create a new folder here and let's name it this quiz and now inside of this quiz let's import this quiz folder or component and we want to update the Imports so visual studio code does this automatically which is very very nice so let's save that and also what we want to create inside of this quiz folder I want to create a CSS file so as you may see in this index file we have all this code which is public code but also something related to the quiz component itself so what I want to do is to move this uh this CSS code into a separate CSS file so inside of our quiz folder let's create a new file and let's name it careers.scss like so and now what we can do is we can just take this code from the container you can save this index file obviously now it's broken so we're gonna save it here and now we need to import it inside of our quiz so just import quiz Dot scss like so and now we don't have access to our variables here no so what we can do is actually we can extract the variables in a separate file and then we can access those variables there so what we can do is we can create a new folder for Styles so let's create a new folder and let's name this folder as Styles like so and make sure that it's inside of the source folder so let's move it outside and now inside of the Styles folder let's create a new file and let's name this file as for variables you know inside of the index.css file let's just take this and let's just move it inside of inside here like so and now what we can do is we can go to the quiz and import those variables so let's just import and let's find what is the URL of it so inside of these styles or actually we need to go one step up and then inside of these Styles and then wire.css like so now if we save it it should work like so but I want to move this index file as well so now let's let's see here inside of the index.css file so I want to move it as well and then import these variables here as well because we need the variables inside of the index CSS file so let's first save it it's going to break our project for a second let's move all the styles to be installed inside of this Styles folder like so and now we need to import the variables because we are using using the variables for the background for the color and whatnot so again let's import and it's inside of the same folder and we need to import the bars like so but one thing we need to update inside of the main.jsx we actually need to update the import of our style so from styles inside of the index fcss like so so let's just refresh our application and it works like expected beautiful okay so let me just see what else we can do I think that actually this basically sums up what we can do for the refactoring and we have basic basic setup now so what we can do is we can start adding new components and new features you can obviously let me close all the files and what we can do is we could obviously optimize our quiz application because it's a little bit long so but we can do that later if we have time so for but for now I want to add first components so what I want to add from the features is I want to add a counter feature so basically what it means is we're going to add a limited time that you can answer the questions of on this quiz so basically on top here is going to be counter and we're going to be able to answer those questions uh before the timer comes down so let's add a new component and now we can create all the components inside of our components folder here so let's name our component let's add a new new folder and let's name it as answer timer like so and make sure that this folder inside is inside of these components folder not inside of the quiz and here let's add a new file and let's name it answer timer.jsx like so now here we're going to create new functional component but before we create our component let's add a CSS file so this is the you know basically the pattern that we use for all components so we have a component and then we have CSS file next to it and the naming convention is exactly the same so answer simer.scss like so and now what we need to do is just import it mix or actually this is not a CSS import so just import the file which is answer timer Dot scss like so okay and now let's create our component so it's going to be a simple functional component so let's name it uh answer timer and let's export it export default cancel timer like so and the only thing uh which functional component needs to have is return statement like we discussed on previous sessions so let's just say hello like so to to see if it works correctly and now what we can do is we can include it inside of our quiz application and I want to include it here next are actually above our component here so let's include it here foreign like that so what products we need to import our components so here in the import section excuse me so import timer from answer timer here and there you go here we have this hello so now we need to style this and make it like we wanted so this is going to be a very simple component so because essentially it's just going to be a div a bit of progress bar and that's all so let's just create a div and let's set a class name so this is how you add questions obviously in in react we covered all the basics into the previous Workshop so I'm not going to be repeating myself but basically uh class is reserved uh name in a keyword in in JavaScript so that's why react has this class name to give to differentiate it between the classes which you can create in JavaScript so for the actual class name let's add a class answer loader container maybe answer load a container or answer timer whatever timer like so and then inside of this we're going to have another div and this is going to be for the actual progress so let's just add a class name of progress like so okay and now let's add some style to this component so first we need to import variables so let's hide it inside of our style folder and let's import expires folder so that we have it available here and now let's first Target this parent component or actually parent div like so and we want to make this um as positioned absolute so but obviously to make it on top of our component we would need to make our quiz uh quiz container as relative so set the quiz position relative like so okay and now let's add position here to be absolute and now let's add the position top to be zero because we want it to be here on top left so top zero left to be zero width we're gonna take a hundred percent and we're gonna add some border on the bottom so border batch bottom and I'm just gonna add one pixel solid and use disabled color okay uh we cannot see anything because we don't have height added to to our child or our container so inside of our container let's target the progress here and inside of the scss obviously we can nest we can Nest our CSS rules so we want to set height to be 5 pixels let's set the transition duration to be one second so it looks very smooth uh we're gonna set the initial width to be zero but obviously we're gonna update so let's say for example to set it to 50 percent so and let's set the background to be red so that actually you can see how it will look like once you're done so you can see this is the progress that we're going to be building uh or actually making making it work so but lets it set it to here bits to be only zero at the beginning and inside of the jsx code we're going to update it to take the width depending on the actual con counter so width to be zero and let's add transition timing function to be a linear so we don't want to have any easing or ease out we just want a linear motion like so and now inside of our okay we have created that and now inside of our answer time in jsx uh we want to do a couple of things so first we want to start uh taking the timer so for that we need uh set interval so let's first import couple of things that we need to implement that so first we're going to need a couple of hooks so import use effect from react use effect is a hook in which you execute your asynchronous code or uh or some side effects so for example set interval set timeout are the functions that you would execute inside of this use effect hook or when you make an API call or subscription or whatever asynchronous code you're trying to to write so how we write use a fact is we just call the user fact book and it takes two arguments the first argument uses a function that you want to execute and the second argument is array of the dependencies so if any of these dependencies changes this use effect hook will re-run again but so if we want to only run this hook once we leave this array as empty so this is what we want to do initially when we load our loading component we just want to load this once so what we want to do here is you want to call set interval and on every single second we want to change the counter so inside of the interval we want to execute a function like so and the interval is going to be like I said 1000 milliseconds which is one second and here in order to track the counter we need to import u-state hook which we covered in the previous Workshop so I use state like so and now what we can do is we can create new variable so let's create a const and the name of this variable is going to be counter and update a function for a variable is going to be set but lowercase at counter and we're gonna set initial state to be zero so we're going to start start at zero so every single second we're gonna increase the counter by one so how we do that is we call the set counter and we take the current value which we can access inside our seller function and then we just return back value increased by one pixel and how we can test that is we can use this counter inside of our let's say progress and when we refresh you can see and every second it it increases our progress nice okay so let's remove that so what we want to do next is we want to once we are once we update the counter we want to update the width of this progress so we need another use effect work or actually before we do that one very important thing to know is that we cannot leave this interval uh function like that we need to clean it up in case you destroy your function this food this would still continue to to run so how we do that is we need use wrap hook so let's import qrf work so your Draft clock is hook which you use to make a reference to maybe document object models for example you want to focus on an input field or you want to change color of something or you want to make a reference to set an interval function or object so this is the the great use case for it so let's create a new constant and let's call it interval graph which stands for reference and now just initialize our reference your draft code actually so how we can assign or store the set interval object inside our office I use uh interval ref is by accessing the current property we just assign the current property to a current property of integral ref front set interval and now how do you clean up from use effect Hook is you just add return statement so you just need to return a function so how we do that is just return something and that something is a function which clears this interval so we just call the native peer interval method or function and we just pass in the current and that's how we clear the intervals inside of the use effect Cooks entirely functional components and now like I said we want to update this progress with uh the loading so how we do that is let's add another use effect hook takes again function and the second parameter is again list of the dependencies but this time we want to rerun this code every time this counter changes like so okay so what we what we need to do is first we need to add additional variable and instead of that variable we're going to save the percentage of what has been or what time has passed so let's add one more variable and let's name this variable as progress loaded like so and let's add this setup function set always loaded and it's also going to be zero at the beginning so zero percent so what we want to do uh first we want to update uh on every counter change and how we update our progress is we use counter and we divide the counter by the duration length so let's say that we have duration from the parent component so this is something very uh variable uh which can be changed on different places so let's say inside of the quiz application uh here on the essence timer we set the duration to be let's say 10 seconds so we can access duration here as a property and we can divide it duration and so how we set uh progress in percentages is we just divide the counter by the duration so in in this case would be 10 and then we just increase that or multiply that by 100. like so and now we have the progress being updated every single second and stored inside of this progress loaded variable and uh the second thing which you want to do is we want to check if we reach the end of our progress which is 100 obviously so what we need to to check if counter is equal to duration so here we set the counter to be 10 so it's going to start from 0 1 2 3 4 5 6 7 8 9 and then we reach 10. what we want to do is we want to clear the interval and stop that so how we clear the interval again similar to what we did here on our use effect Hawk so just clear the interval and again we can access its interval rough current and apart from that what we want to do is we want to say to our Parent Quiz function that our time is up so it can perform uh some certain actions so for example if time has up we want to mark that we haven't answered the question correctly in the giving time in a given time and we want to proceed to the next question so we need to pass a new function and let's name that function let's see how we're going to name that function so let's say handle handle time up let's say let's call it const handle time up so this is just a simple header function and for now we're just going to leave it empty and we're gonna pass here and let's name our function on or actually our property on time and here we're just going to pass our handle time up function so here once the time is up we want to call this function so we can perform some operations like I said previously but as once we reach the end of uh the timer we want to give it one second because as you remember here we add 20 transition duration to one second so once we reach the actual 10 10 second it will take one more second for the animation to complete so we so we want to be in sync with that and let's add timeout here for a one second just set time out one second and then we want to call our function which we are passing here from the quiz application which is on timeout we can access the function from the property and we just call this function on timer like so so what we can do is we can actually just test if this work and we can just alert time is up just to see if it works okay now let's refresh and let's try again we are not seeing anything in the UI because we haven't started interfer interfering with the progress itself but after 10 seconds we get this time is up okay nice this works as expected so let me remove this alert because I hate alerts to be honest with you like so okay so the next thing which you want to add is obviously to update this progress and to have uh something visually represented so how we do that is we can use the style property so let's access the cell property and style property receives an object so inside of this first curly brackets uh this stands for expression and the second one is for the object itself and we can update the width so we can set the width to be the progress which we actually saved here progress loaded and we just need to we just need to add the percentage at the end of it so like so and what I want to do as well so you cannot see it now but let me just save it because the background is transparent so if I go to answer time let's add a background color to just red let's say now let's refresh and now you can see our loader or actually timer is working as expected but what I want to do is to make it even more interesting so let's remove this background color and let's make it Dynamic so depending on the time we change the color so how we do that is we just access this background color property on the style here and we want to to check what is the current uh progress so let's open up ticks and we're going to have a couple of like so and you're gonna have a couple of checks so inside of this expression first let's check if progress loaded is less than 40. so if it's less than 40 what we want to do is we want color to be light green it's green like so but if progress loaded is less than is more than 40 but less than 70 here let's put it 40. so if it's 40 if it's less than 40 we want it to be light green if it's more than 40 but less than 70 we want it to be orange and it's more than 70 we want it to be red so it gives like alert to the user that's the time is going to you know expire so let's see how it works let's refresh our application and as you can see it starts green then it changes to Orange and then it becomes red beautiful but now what we need to do is one it gets to the end itself we want to update the UI so actually what we want to do is we want to set basically answer is wrong because the time has been up and we want to proceed to the next question okay so what you need to do is we first need to set enter we're going to update our answer function and let's set the answer to be false like I said and then we need to call our one click next function and just passing let's pass in this value because and I will explain you in a second so what we need to do is we need to add new parameter and let's name this parameter as final answer final answer and then we can check for this Final Answer instead of this answer here and we need to update this on click next here as well so let me just add a function and let's pass in an answer here so why I did that let me just explain it for a second so if we update the set answer and we call on clicks on click next the answer inside of this function is not going to be updated yet because it needs to be updated on the next re-render so on the same re-render it will update it but it will hold the value of the previous answer so in this way we're actually making sure that we are passing in the latest value of the answer which is false in this case so what we are doing is we are setting the answer to be false and we are we're telling let's proceed to the next answer to the next answer so or to the next question actually so let me save and let's see if it works so let's refresh we are not uh selecting any answers let's let's wait it to to go to the end or actually we can even change to five seconds so we don't have to wait for 10 seconds but as you can see now we selected the answer is wrong and we switch to the next question so let me just set it to five seconds so it's a little bit faster but the problem now as you can see uh we haven't reseted our progress so what we want to do is when we proceed to the next uh question we want to reset our progress so the easiest way to do this is I mean we can do it this multiple ways one of the ways could be to reset uh all the properties that we have inside of our answer time but as we're using this uh transition duration uh property on CSS it will take one second to reset this loader and it will show it how it's getting backwards which I don't like so what I'm going to do is I'm going to do it like the simplest way is just add a new flag and I'm just going to show this flag to false and then to true so basically hide and show this component so it's reset it in the Dom itself so what we're gonna do is let's add a new a new uh variable and let me just call this variable as so it's going to be a new variable and let's name it as show answer timer and update a function set answer that show answer timer and initially it's going to be true so when we load our component we want this loader to be visible like so now what we want to do is we want to check here if this is true then we want to render this component if it's not don't render this component so how we do that is by adding two a percent uh characters so if this on left is Right render this component you also have this ternary operator when you add conditional so if this is true render this this entire section otherwise remember this section so depending on how many uh actual cases you have you may use the ternary operator or Ampersand characters so in this case this will work okay so now it's always true and we always see the progress bar but what we want to do once uh once the time or actually once we reach the next so whether time has been up or we clicked on the next button we want to reset our progress so what we need to do is here inside of on click next what we need to do is we want to set uh set show timer answer timer to false so we want to hide it first and then what we need to do is we need to use here at additive I mean it doesn't have to be at the end but for like logical reasons I like to put it at the end of the actual function we need to use the set timeout and I will explain this in a second set timeout and set them out obviously just receive the function and you don't have to specify what is the actual value so why do we we need to set it inside the of the timeout if we if we just call it like this I'll try to be set timeout the value false and value true would be changed in the exactly same queue render so what it means is it means that the it means that the component component or the actual variable value is not going to be changed because in the same rendering queue you're updating the same value twice so initially it's true but you're changing it to false and then you're returning back to True which doesn't which doesn't change it at all so what we need to do is initially set it to false and this gets executed in the rendering queue but then all the asynchronous code like set timeout is getting executed afterwards so then it reappears with the function so now let's let's try if it works or not so let's refresh our component so let's wait for five seconds to expire and then boom we can see it starts again so what we actually can do is we can wait for the end of this questionary and to see uh if we got all the wrong answers because we are marking the answers as wrong on the time up here here set answer to false and let's wait for the last question and here we can see total questions 5 total score is zero correct answer zero and the wrong answers are five so our timer is working as expected beautiful so let's say that we want to add a different type of answers or actually questions so what we can do is we can add one more question so if we go to let's say we go to here to constants and let's copy this first question because we need that same structure we have multiple choice questions but we want to add an input so for some questions it's not enough just to answer it using like the the choices but we can add questions using the input itself so we can input different values so let's say uh the type of discretion is going to be fill in blank this is shorthand for that killing blank like so and let's set we don't have any choices and let's set the question to be I guess so first we have this blank space and then we ask provide a way to pass data from one component to another then we just say fill in the blank and Dot and now the correct answer should be props excellent props provide a way to pass data from one component to another foreign let's add new section inside of our quiz uh component here so here as you can see we need to First detect what is the type of the of the question so here we can access the type let's reduce the width here and then we can check if the type is multiple choice question we can render these choices if it's not we need input so but we can there's multiple ways how you can do this uh you can create new component or you can create a function inside of this so it's up to you uh for this purpose I'm gonna create just a simple function inside of our quiz component we can optimize it in uh future workshops obviously so let's create a function and let's call this function as get answer UI for example in lack of better term so we need to get the type and depending on this type we're going to render different things so first and I mean as default we want to render multiple choice question so what we can do is we can just take the unordered list this one here and just place it inside over here and how you execute this function is just instead of this unordered list we just open up expression and we just call our function here and now if I just run this it should I mean for the actual parameter we need to set send a type like so I mean we could even access the type yes from the current question we can actually access the type from from here so because we don't need it because we are actually destructuring our questions here so yeah we don't need to pass it as a parameter yeah this is fine so if I now if I just save it and if I refresh it we should see no changes or actually we we have some issues so let me just debug it uh one obvious reason because we don't have the choices on the first question here we remove the choices so what we need to do is actually let's let's check if the type if type is equal to and we said he is feeling blank filling blank like so we want to return back something different so let's return an input input and yeah we can we can code it later so this is what we would get yeah now it works so on the second question yeah we get back our multiple choice question for the first one we just get the input itself so now what we need to do is let's apply some stats because our input just looks terrible so inside of the quiz let's add some CSS so let's scroll a bit down and here let's add an input and I want to add a border so let's add a 41 pixel solid and let's use disabled and let's set border radius to four pixels let's add some padding on top and bottom let's set it to 10 pixels and left and right to 20 pixels like so let's add a width to be 100 percent let's add some margin on the top to be 20 pixels and I want to set the Box sizing uh to be the board box so it's not more than what we expect from it to be let's see how it looks like that's more like it okay let me close the quiz so here what we want to do is we want to do a couple of things so first uh we we need to create another variable and using this variable we're gonna handle our input so let's create this variable and let's name it as input answer so const as input answer and the updated function is going to be set input answer like so and now we're going to use U state cook and let's add the initial value to be empty empty string like so okay so now what we can do is for this input field we need to give it a value so here we value of its input and what you need to do is to handle on change events so on change event similar to regular HTML inputs we just have this camel case and we want to call new function which we're going to create in a second so let's call it handle handle input change like so let's create this new component here L input change and this component takes event from this input or actually this function takes event here so what we want to do here is we want to First just set the update this input answer variables so let's call it set input answer to be event dot Target dot value like so and we want to check if this is correct answer or not so if event dot Target dot value is equal to correct answer again we want to set the answer to be true set answer to be true otherwise you want to set the answer to be false answer to be false like so okay and that's pretty much solves it so what we need to do next is we want to check we want to disable the next button until let me just refresh for a second and let me increase the duration to 15 seconds so that we have time to explain what's happening so first we want to check uh if there is if there is something entered so if you start typing props you can see that this is still disabled because on the next button itself let me just see where it is um this is next okay so we are disabling only if answer RDX is null so what we want to do is end input if there is no input answer so if we have input answer we want this to be button to be enabled so let's save it now we should have this button enabled once we start typing like so so let's say that we input the proper props answer so let's go and actually let me reduce the duration so that we finish this faster I mean it doesn't matter but yeah so let's type in props and let's click next uh the answer here is virtual Dom for this one is user interface for this one is again props the next one is Javascript Babel is just a compiler and as you can see we have total six questions total score is 30 and we have correct six answers so beautiful so what we implemented in this one is we add this progress bar and we added uh input uh input field so we have multiple types of questions as if you go to the constant here you can see we have this type fill in black and we have this multiple choice questions the first thing that I want to do is I want to fix one bug which we created on the previous uh session so let me just show you so if you select some of the questions and if you click on next one second before it ends it goes to the fourth so you can see it skips two questions so that's a bug that uh this uh this bug is due to the delay that we created the last time so how we can fix it is let's go to components and let's open this answer time so first thing that I want to do is I want to reduce the transition duration so this was causing this issue so instead of one second I want to make it 1.0.1 seconds which is uh one tenth of a second and now we need to update here are answer timer so to refresh faster than just on one second so the first thing that I want to do is instead of setting this interval to repeat on every second we want we want it to repeat on every 100 millisecond like so and what I want to do next let me see so here I want to increase it by 0.1 because we are not increasing anymore by one and here I just wanted to to be to make sure that counter is equal or greater than duration like so and as a matter of fact we don't need now this timeout because we remove that one second delay here um yeah and I think that should show us uh this issue that we have so let me just save this and if you're using prettier like I am uh then you will get everything formatted so let me refresh and let me try again so let's try let's actually skip the first one so let's try the next one let's set original Dom and click next and there you go so it's now on the next question okay so the next thing that I want to do is I want to fetch the questions so as you can see at the moment we are importing the questions from constants here and we have hard-coded that so what I want to do is I want to use an actual API to show you how you can fetch and to show you how you can fetch in in react so what we're gonna do is go to the description box of this uh this workshop and you will find a link to this mock API which I created using this mock API service this is a great service if you want to mock something because the purpose of this Workshop is not how to create a backend endpoint but rather just to learn react so that's why I highly suggest you to go over there so what I want to do is I want to go to our app component let me close this these files and inside of our app component we'll need two things so first thing which we need to do is to import use effect hook so use effect hook and using this user fact hook uh we're gonna make an API call or actually this is going to be the place where we're going to make the API call and we will need you state hook to handle what we are getting back and to store that result so now inside of the app itself we want to Handy covered use effect hook on previous session in detail hopefully you can see my screen again sorry for that uh just let me know if you can see it now I think that you can uh yeah there was some issue with the platform itself so just to cover up where we are at so we are in the app component and we imported use effect and use State hook so now inside of the use inside of the function app I was just gonna initialize the use effect cook and be covered use of echo on the previous Workshop so essentially we're just passing in a function here and we are passing in the array of dependencies so we're just going to execute this one so the array is empty and inside of this function we're actually just going to call our get questions function and now let's create this functions so we can create here this is going to be just a fair Arrow function like so and this is going to be asynchronous function because we're going to make an external API request okay now inside of this function what I want to do is I want to add try catch block and inside of this try catch block obviously if we make any errors we can just console log the error obviously this is just for this purpose but in real case scenario you want to store this in some kind of analytics software or to display to user that something wrong has been happened so but inside of this try block let's create a response payable and we're gonna store the result that we get back from the actual fetch so we're gonna use the fetch method to make an API request let me just close this tab and for the URL we're going to use the mock API URL or actually we can copy it from here and we're just going to add the URL like so and the actual endpoint is questions like so so the actual response we're gonna store in the this variable response and then what we're going to do is we're gonna convert that to Json so let's add a new variable and let's name it questions response and we're just going to use response and convert that to Json so like so and this is also asynchronous operation so we need to add a weight in order to weigh the result like so so now we have the results and let's just console log them to see if we get it right console log question response like so and Let me refresh our application let me open up the terminal and inside of the console we can see that we got the array with our questions beautiful that's exactly what we wanted so now we want to store these questions in a variable and pass them to this quiz component so now we can use our use State hook to do that so inside of the app component let's create a new variable and let's name it questions and we need update a function and let's name the updated function as set questions like so you can now just initialize our usted hook and initial value is going to be empty array like so and now what we want to do is once we fetch we want to set call this set questions function and we want to use these questions response to store it like so and now instead of sending this hard-coded quiz questions we can remove them and now we just need to send the questions here so let me remove this and Let me refresh okay when we're just loading our application we are passing in an empty array and that's why we don't get any any results here so what we need to do is we need first to check if we are if you do have questions or not so let's check if questions don't length is greater basically than zero in that case in that case uh we will gonna render this otherwise we're not gonna render anything so basically if you have real uh application that you maybe can show a loader or something like that so yeah let's just save this and as you can see we get our questions but this time we are fetching these questions from the actual mock API I can close the mock API because we don't need any more beautiful uh okay the next thing that I want to add uh so let me close this and I want to go to the quiz component and I want to do a little bit of refactoring there so what I want to do is I want to create a new component so inside of this folder I want to create this results component so let me just show you if you go to the quiz component and if we scroll down we can see that we have this results section and I want to export that to new component and add some additional things so let me show you so inside of the components let's create a new folder and let's name it result like so and inside of this folder let's create a new file and let's name it result Dot jsx we will also need a new file for Styles so result Dot scss like so in here we're just going to create functional component so let's name this component as result so this is basically the result here of our quiz and this is going to be a functional component and we want to export the on bottom so export default result like so okay now instead of the return statement what I want to do is I want to return basically it's from the quiz application so here we can just take this entire section let me cut it off and let me paste it here like so so in order to make this work we'll need a couple of things so first we need this questions length and we need this result score and also we need this on try again function so we're gonna pass those 3D properties so first let's say that we're gonna get uh total questions let's rename this property so let's name it as total questions then we will need result to access all of these properties from the result and we will need on try again function like so so now let's import this function here in our quiz application or actually quiz component so let's import result from result like so and now we can place it inside of our quiz return statement here so result and for properties we need to Pi to pass in let me just see what we added so we need result so pass result property there then we need this method which is on try again so just pass in that and the last thing that we want to pass in is this total questions and that's going to be these questions dot length foreign like so so here we're gonna pass two total questions you're gonna pass ask question.lent so let me save this like so and let's refresh our application or actually there's one thing that I forgot so we need to add CSS as well so if you go to the quiz CSS let's take the result div as well so let me take it from this place and let's add it to the result here like so and now we need to import it inside of our component so let's import it on the top so let's import or actually it's in the same folder and name of the file it's result.scss like so and now let me just see it should be good but for some reason I don't see it being loaded properly so let me just see if we added okay we added this let me just see if there is a issue with the name itself so we double check that here or we probably need to refresh our application so let's do that okay there's no problem we are actually not importing the variables so that's why it doesn't work so inside of our file we need to import the variables so let's see where we store the variables so let's use the import and variables are in two folders up and then Styles folder and inside of the virus file like so I know what it what it is so we are actually having the uh wrong Imports so this needs to be default import so just remove the brackets like so because this needs to be a default import like so now if you refresh you can see it works as expected so now let me just see uh at the end of our quiz if we got the stats correctly so let me just skip to the end of this quiz and now we have our scores uh being styled correctly okay so so the next thing that I want to add here is I want to add the ability to save our score and then once we refresh and restart our our session we can see the leaderboard and what is like the best score that we created so let me go to this results page here let me close all these other things and now let's start building there so here below this on try again we want to add react fragments and Below these react fragments let's add a heading H3 heading so let's say here enter let me just close the sidebar so it's more readable enter your name below and let's add a break line to save your score like so here and then we want to give an input so that users can enter their you know their name and we're just going to save the score that we that they achieved so let's add an input and for this input we will need a value and we're going to store that value actually assign that value using the use State hook so let's import use that hook import use statehook from react and then we're going to create new variables so let's name this variable as a name and update a function as set name like so and we just want to set initial state to be empty strings like so okay and now we can add the value to this input to be name and we want to update on change so let's call it on change event and what we want to do is we want to take event and I want to call this set name function and to update our name variable with the event.target.value so we want to to take the value from our input here okay let me save that and let's just add a placeholder so it's more nice I mean it's more descriptive actually so let's set a placeholder and let's say your name so that users know what actually they need to enter there I mean there's a title here but yeah this is more more nicer and we want to add a button so here we're going to say save okay and now let's add a new on click event and here we want to handle once we click on our button so let's say handle save and we're gonna create a new function here on top so let's add a new function handle save it's going to be Arrow function like so and here we want to store the results that we got from the actual result score so yeah and we're gonna use local storage to say okay so the next thing that I want to do is I want to take the values from the score and create new object so let's name that object as score so it's going to be new object and this object is going to have a name so it's going to be the name which we enter in this input field and it's going to be we could omit the second name and it it's going to have the score property as well and you're just going to take result.score like so so this is uh the Json object I mean the the object that we want to save in the local storage so uh we are also going to need additional variables so for the actual array of this course so let's copy paste this line and for the second variable let's name it as high scores and let's name it the updated function as set high scores and for high scores high scores are going to be an array of different high scores obviously and we will need another flag so as you can see uh when we enter the score and when we click uh the button that we created here save we want to hide this div and we want to show the table or leaderboard right so let's add another flag for that and we can duplicate this and let's name the one this one is show scores and the updated function as set show scores like so and let's initialize it to false okay like so and what we're gonna do now is uh basically we're gonna create we're gonna update this high scores array so we're gonna add our score to it and save it so let's create a new variable and let's name it as a new high scores and here I'm just going to destructure our current scores so high scores so just describe destructure them and then we're just gonna append our new created object new score and then what I want to do I want to sort them so let's use the sort because we want to display the the best score on top and then we want to rank them you know based on the score that they achieved so let's sort it and we accessed the first item in the sort array and the second and how we sort them is by using the score so we want to take B DOT score and we detract it from a DOT score and using this sorting actually we don't need this one in using this score property we're gonna rate them and sort them like so okay and now what we can do is we can store that so let's first set it to high scores so set high scores to be this new value which we created and that is new high scores and we want to set the flag to show the actual scores so this flag so now let's set it to true so set set show scores flag to true like so and so basically we're going to use this flag to like I said to alter this div so let me just save it so this is the div that I'm talking about and the the most important piece is actually to save that in the local storage so that we can uh retrieve it back ideally in ideal use case scenario you would have an API point where you can actually or database where you can save all these results but for now and for this application which is we're just going to use the local storage so we're going to call the local storage Dot set item and let's name the item itself as high scores and here we need to pass a string because you can only store string in the local storage so we need to call the json.stringify method method to convert this array in in string and what we need to pass in new high scores this one and with that we have created the new high score so what I want to do now before we actually retrieve those scores back I want to create a new div and or actually new suction and inside of this action we're going to create our table so let me just see below this uh let's just add a new flag so here and I'm just going to say if show scores is false so if you don't want to show scores in that case we want to render just a second if I get it right in that case we want to render uh this section otherwise we want to show the scores so next to it let's add a new section and here we're going to say if show scores I mean we could even set conditionals so we could do it like if not we can add a ternary operator so so if we want to hide the show scores so basically render this one otherwise let's render new section so inside of this section we're just going to add a table so let's add a table like so and inside of this table we're gonna have three columns so let's add first header so T head and instead of this head let's add a row and inside of this row we're gonna have three columns so let me paste this three times so for the first one we're gonna add a ranking and this is going to be basically just the numbers from one to you know two other numbers the second one is going to be name of the player and the last one is going to be the score like so and then let's add tea body any side of the body that's what we're gonna do now is we're gonna take all these scores here that we have and we're gonna render them but let's just create something static for this first use case so let's add a table row and for the table row we're gonna have three uh table divs uh or table cells actually and for the first one let's just say one and I just multiply it three times and then let's say for the second log we need name and we need to score let's say 15 like so now let's just test this functionality so if I refresh uh let me wait and actually skip until the end of this section and then we should be able to see once we enter our name let's say Bob and we click on Save we should get our table so the first thing obviously that we need to do is to apply some Styles so it's a little bit nicer so okay so here inside of the result the let's add a table and first let's set the width to be 50 so it's a little bit bigger than let's set text align to be left let's add some margin so it's a little bit more separated from the top uh button so let's add 50 pixels on top let's make it centered so set the auto for left and right and let's add 20 pixels on the bottom and let's add borders as well so let's add the Border collapse to collapse like so and now just let's just add table rows and for the table rows we want to add this border so border one pixel solid and that's it yeah we can use default one here uh these three columns are only being stacked below this one so because we wrapped our body with our head so let me just fix this and there you go this is how how I wanted so now we can use high scores that we actually created and not hard coding this and create uh create actual data here and dynamic data so let's use high score highscores.map and we're going to iterate through our items so let's say we access the high score property or actually let's name our item is high score and then what we want to do is we also we will need to access the index itself so like so and then inside of the loop we will want we will need to return this table row that which we just created here and we'll just update these static values so what we're going to use here we're going to use for the first one we're going to use the index and we're just going to increase it by one because it's starting from zero so we want to obviously start from one for the name we're going to use the value which we which we created here and that's here the name so high score dot name and for the last one we want to use the score and we name that one as score like so so let's add new property here on the bottom high score DOT score like so so let me refresh it and we actually now got the the actual real score that we saved it so and let's let's just try this again so actually we want to do we actually want to perform some resetting when you click on try again we want to reset our our state here so let's I will need to add an additional function so let's name this one as handle safe so actually we have handle save here that's the one that is saving and we want to add additional function for on try again so let's name it as a Handler try again so here because we want to reset the state once we click on try again we want everything to to be exactly the same as when we started uh doing so so what we want to do here is let's create a handle try again function it's going to be Arrow function and we're going to call this function from our button here on try again okay so what we're going to do here we're going to reset the state of set show scores so let's call that function set show scores two false we want to reset the high scores to empty area again so let's call it set high scores to an empty array and then we want to call this on try again function when we reset that and uh there is there is one more thing that we need to to do actually so uh when we actually reload our application we will lose the the actual results that we created and that we stored inside of the local storage so what we need to do is we need to create uh use effect work and using this use effect cook we want to once our component has been created we want to fetch the actual not fetch but to retrieve the data from the actual local storage and save that to our high scores so for that we will need use a fact hook so let's import use effect work here and let's initialize our hook here so let's call use effect hook and we want to execute this hook only once so let's leave the dependency array as empty so what we want to do is we want to set this set high scores array and uh the thing which we retrieve from from the actual local storage is a string so we need to use that string and convert that to the actual array so how we do that is using the Json dot parse method or function rather and then we get local storage dot get item we use this function to get the item from the local storage and we use let me just see what was the the actual name or the name of the item that we named so it was high scores so we want to retrieve the high scores or in case uh this is like the first time that we are loading our component we want to pass in an empty array so that we don't get into any uh any errors like so so let me save this and Let me refresh our application and let me try again so let's say that to answer all of the questions so for the first one is props here is the virtual Dom uh this one is your user interface framework this is props this one is Javascript and this one is Javascript compiler and we got score 30 and yeah so now we can enter our name let me enter my name slogan on and let me save this and you can see we got the score uh slogan uh as one so yeah now what we can do is we can try again and to see if this score got saved so let's try again and actually as you can see here we have this uh issue so we need to actually reset uh reset our input field so let me go quickly inside of our quiz component so here inside of the quiz component inside of the on click next what do I want to do here is I want to set input answer as an empty string so once we you know reset it it's going to be empty like so okay so let's try again Let me refresh our application and let's fill in the props and now let's make some questions or actually let's make a Wrong by by on in purpose so so that we don't get the perfect score again so here we got total score 10 so we only got two correct answers and let me use different names so let's Muse my last name and actually we got only only uh the last score so what I want to do is I want to check if we are storing that correctly so if you can if you inspect we can use the local storage okay so yeah okay so this is the problem we're not getting uh we're not setting the key to our actual to our actual table rows so that's one of the most important things that you need to add and obviously I forgot it so let's add a key because using the key uh react is able to track which item has been changed in the list itself so that's why we need need it so let's add a ticks and we want to make this from high score DOT score and we want to make it combination of high score of name and the index itself so that we are sure that this is unique because if somebody enters the same name and he achieves the same score we're gonna get the same Index right so like so and let's see okay we got the result normal so let me save this and uh let's refresh again uh here we need to get item uh and we need to pass the string or actually the key of the property which you want to get from the local storage and that was the issue so let me just make sure that this is the same key so this is the high score like so and now it will work okay so yeah that was the issue that I missed okay so yeah now let's see props next virtual Dom now let's make the best score possible user interface props JavaScript and compiler and now let's save it let's say it as Bob and there you go so now we have our scores being saved so let's try once again just to make it sure so let's say that we this time let's make everything wrong so that we make a different score so you can see that sorting is working as well so let's name this one as uh Bob all right and as you can see now it's getting sorted we are getting all the values being saved and this works as expected so I think this pretty much sums up on what I hear what I wanted to do today yeah maybe it's not a lot obviously there's so many things which you can add potentially on this application but I think it's enough to to cover the basics uh to cover the basics of react and to have something to just get your hands dirty and yeah and if you want to support my channel and get a full source code of every single video that I'm doing feel free to check out patreon.com code with sloba to get full access see you there well that's all for this react video and thanks for stopping by and don't forget to subscribe code with sloba thank you for watching the entire video to see more react tutorials click here [Music]
Info
Channel: Code with Sloba
Views: 34,193
Rating: undefined out of 5
Keywords: How to Build a Quiz App using React, how to build react quiz app, react quiz app with timer, react quiz app tutorial, react quiz app with firebase, react quiz app with, react quiz app with database, react quiz app with api, react hooks, react hooks tutorial, react project tutorial, react project tutorial for beginners, react js quiz app, react js quiz, quiz app react typescript, quiz app react js, slobodan gajic, code with sloba, reactjs tutorial for beginners, reactjs, sass
Id: UX5HIrxbRUc
Channel Id: undefined
Length: 134min 39sec (8079 seconds)
Published: Sun Apr 30 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.