We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 151
hey everyone this is Anson today I'm going to teach you how to get started with
learning react if you're trying to
break into front development whether to get a job as a front developer or just as a hobby then this is the right place to be many of you will have different goals with learning react some of you want to build a web application or you want to build a mobile application or both perhaps you've heard about framework such as nextjs and remix both are react based and they provide lots of great tools out of the box for building modern web applications or maybe you just want to build a very simple and plain static website whatever the case is this tutorial will serve as a foundation as all of these goals mentioned will require this initial step of learning react now just keep in mind that we will be focusing on the web based application we won't be Focus focusing on mobile applications but learning react will enable you to learn react native which will allow you to build mobile applications now let's first understand what exactly is react well it's just a front-end JavaScript library and whenever you hear frontend it just really means what the user what the customer the person that is using your product your application will see what they will interact with anything that they can view okay so if you go on your browser and you type in any website in the address bar it will load up the document that is the front end with react you use it to build components which are just renderable bits that make up your user interface so for example you might have a website that has a navigation bar it has a sidebar that you can scroll through posts user activity feeds whatever it is you might have a main section that will display posts made by a user and you can see comments and stuff like that that entire thing is the whole user interface but what makes makes up that user interface are these reusable components which you'll learn more about later on in this tutorial react focuses on The View so in other words what the user sees and what they interact with react is also an unopinionated Library which just means that there's no right or wrong way to do things when we talk about unopinionated tools there's no limitation there's no rule set that you need to follow to use the tool itself okay so you can use react however you choose to now why Why learn React? learn react well first of all it's still in high demand for front-end Developer jobs it's used by many companies including Fortune 500s and startups you can use it to build any type of application so whether that be a web application which is what we're going to be focusing on or a mobile application using a framework called react native or if you want to build a desktop application you can use something like electron or tari it's simple to learn for absolute beginners with zero experience building Progressive web applications now like many things in Prerequisites life there are going to be prerequisites in order to learn react okay so these are Elementary things that every single frontend developer will need to learn first before they learn any front-end library or framework such as you know react angular vue.js you get the point so the three important things that you must learn is HTML CSS and client side JavaScript I'm sure many of you will probably already have these prerequisites down but if you don't know these three things I highly recommend you pause this video and spend some time just learning HTML CSS and clients side JavaScript now many of you will be asking about resources I would recommend w3schools.com this is a free resource this is what I use when I first started learning how to build basic website they have a lot of different resources available on this website to learn anything you want but what you want to do is go to this website and just click on HTML and then you'll see a bunch of different sections that you can go through and you can start off with the basics the introduction of HTML how it works what is the purpose of it what is HTML etc etc and then once you feel comfortable with it click on CSS and then this will teach you how to style your HTML document and then once you are comfortable with that you can then go into JavaScript but specifically you also want to make sure that not only you are trying to learn the actual programming language of JavaScript you also want to make sure you know JavaScript for the client side so you want to go to this section JS HTML Dom JS browser Dom and then JS web apis and you want to go through those because this is actually what's going to teach you how to manipulate the HTML document using JavaScript okay remember that JavaScript can also run on the server side with no JS and on the server side there are different programming interfaces that you would encounter that are not existent on the browser environment okay so there are differences so that's why I specifically mentioned client side JavaScript now before we get started with setting up our react project I do want to mention a couple things that you'll need on your computer in order to actually set up your react project so first make sure you have node.js installed I currently have uh version 20 on my computer but you can just go to nj.org and then download the latest LTS version is what I would recommend you need this because we're going to be using a build tool called vat in order to generate the react project and then we're going to be using npm which stands for node package manager to install our dependencies that are needed for our react project so make sure you have this node.js installed just click on this and it'll download the installation file for you and it'll walk you through the wizard and it's pretty easy to install and in order to verify that nodejs was properly installed you want to go to your PO shell your windows Powershell command prompt or Mac or Linux terminal and you want to type node and then hyphen V and you want to make sure that it has the correct version that you just installed if this works that means node.js is working properly on your computer you also want to make sure that the command npm is working as well so just type npm Hy and V and this will show you the version of npm npm is automatically installed when you install node.js so I just wanted to mention that now for the text editor I'm going to be using visual studio code it doesn't really matter what you use but I figured I'll would just bring that up and in case some of you might not be familiar with Visual Studio code you might be using something else but I would recommend using vs code because it would just be a lot easier to follow along okay now we're going to go ahead and get started with setting up our react project so again like I said before we're going to be using vit which is a frontend build tool that allows you to scaffold front-end projects now we're specifically using it for react but you could use it for other projects as well such as vue.js if you've heard about that framework before so what we're going to do is we're going to go into our windows power shell or your Linux or Setup React with Vite Mac OS terminal and we're going to type npm and now you see why we need no JS as well as npm in our computer so we're going to type npm create V at latest and this will run the prompt for us to create a v project so we're going to give our project a name I'm going to call this react hyphen tutorial and I'm going to use my arrow keys now to select the framework so you want to make sure you select react going to hit enter and then now you're going to select the variant so we're going to go down and select JavaScript and then now we are done so it created a folder for us in the documents folder and it named it based off of our project name so react tutorial so now we just have to CD into the react tutorial folder so CD react hyphen tutorial and there are two more steps that we need to do we need to install all of the dependencies and then we're going to run the react project just so that we can see that it's working so what I'm going to do is I'm Install NPM Dependencies going to type npm install and this will take a couple of seconds depending on how fast your internet speed is because it is downloading these modules from the node package manager registry so that was pretty fast so uh you can see that it added a bunch of packages and then now we're going to go ahead and run uh the dev script we're going to type npm run Dev so this is going to start up our project and we're going to hit enter and now you can see that vit is up and running it took 394 milliseconds and then you can see that it is currently running on Port 5173 so now you can just click on this link or just go to your browser and type in Local Host colon 5173 so I'm just going to go ahead and click that all right so now you can see it's just a plain website nothing really fancy just has some static assets these Vector icons has some text has a button so nothing crazy now let's go into the actual code let's go into our text editor so again I'm going to open up visual studio code and I'm going to have my project open up just like this now there are a lot of files in here and it might seem overwhelming but I promise Project File Overview you a lot of these files you don't really need to worry about we'll go through each one very very quickly so for example we have our V.C config.js file you're probably not going to be working too much with this as a beginner you can leave this file alone but if you ever want to make configurations to your your V build tool command you would do that inside this object over here okay we have a read me file nothing crazy with this we have our package.json file so this is our manifest file it has information about the project itself and you can see we have scripts set up over here that Dev script that we ran earlier is right over here and you can see it's just an alias for this V script and then we have our dependencies listed so remember earlier when we ran npm install what happens is it will look inside this package.json file and it will install all of these dependencies listed over here so it downloaded react and react Dom these are two separate packages and then it also downloaded all of these Dev dependencies or developer dependencies which help enhance the developer experience when you're working on your project and all of these packages are hosted on the npm registry and then it downloads to this node modules folder right over here so all of those packages all that code get it's downloaded and stored into this node modules folder in your project we have our package lock. Json file we're not going to worry about that I'll come back to the index.html file in just a bit but I just wanted to mention that we also have our get ignore file and we also have our eslint file you're not going to really need to worry about these things unless if you want to use eslint uh if you're a complete beginner don't worry so much about it I don't want to over overwhelm all of you so we have our source folder and right now you see that there's a lot of stuff inside The Source folder but you know what I'm going to do is I'm going to actually delete all of these files except for one file so let me go ahead and right click and delete everything in here and I encourage you to do that as well so that way you don't get overwhelmed with everything that's happening okay so now we're going to go into this main.js jsx file so remember delete all the files except for the main. jsx file the reason why we're not going to delete this is because this is our entry point to our application so this is the root file for our react application so you can see over here that we have a couple of import statements in fact I'm going to go ahead and remove this import app from app.jsx because we just deleted that file so that file no longer exists because you cannot import a file that doesn't exist otherwise you're going to get an issue we're going to also remove this index.css file because we no longer have that file and then since we remove that app import I'm going to also remove this app tag over here and this looks like HTML and in fact just a sneak peek this is actually how you render components in react but I'm going to go ahead and remove this as well okay great so now that we have a lot less stuff to worry about let's walk through what's going on in this main. jsx file and why this file is important so the first two things is it's importing react from that react module and it's also importing react Dom so this allows us to actually have these methods called create root as well as render and what happens here is we need to set up a root for our react Dom because remember react Dom allows us to actually render these react components to a virtual Dom so doesn't actually render it to the actual document itself it renders it to a virtual Dom which makes a lot more faster so what happens here is we call this create root method and you can see as an argument to this method it uses this get element by ID method that's part of the document API and it it it looks for an element by the ID of roots now if you have went through the basics of client side JavaScript this might be familiar with you if it isn't that's okay all you need to know is that this is using the browser API to search for an HTML element by the ID and we're specifically looking for uh an ID of roots okay once it looks for that ID of roots it's going to go ahead and call this render method and then this is where we're going to want to actually uh render our components earlier you saw that it had this app tag right over here so it was actually rendering the app component which we deleted so don't worry in fact what I can do is I'll just leave this empty for now and I want to show you what actually happens when we go into our browser okay so what I'll do now is I'll go into my terminal and I'll run npm runev and let's go ahead and refresh the page right now and you can see now we just have a plain blank page that has nothing because we deleted everything okay now if I were to actually just uh set up a random div over here let's just say hello world you'll see that that hello world text will appear in the document and so will that div so if I actually go to the browser tool so you can actually easily access these browser tools by hitting control shift I uh or if you just right click and then click inspect it'll open up this browser tool over here I'm currently using brave but this works on really any browser and then what you want to do is you want to uh go to the elements section and you can look at the HTML over here and then you can see right over here we have our body tag and then we have uh some tags over here as well okay so now pay attention to this div right over here let me zoom in a little bit you'll see how it has this ID of roots okay and then it also has this div this is the div that we just rendered to the Dom and it had our hello world text okay so this div is what is being looked for right over here okay this this ID root can really be anything you want okay it can be main it can be root you can call literally anything you want now I'll show you what happens if we wanted to uh search for a different ID so let's say if I type main instead of roots right now it's going to go ahead and give us an issue in the console it's going to say Target container is not a Dom element and that's because there is no element in the document that has the ID of main now if for whatever reason you want to change the ID I'll show you how to do that so we're going to go back to our index.html file that we skipped over and you can see that there's a bunch of plain HTML that you should be familiar with okay we have all of our basic HTML tags we have our title tag in the head tag very simple stuff we have our body tag that I want to focus on and you can see right over here we have our div tag and notice how this div has that ID of roots okay so earlier when we had this argument as root it was basically looking for this div right over here okay well let's go ahead and change this to Main and which means that we're going to have to have an element that has an ID of main so I'm going to change that to Main and now you'll see that the error actually goes away because that document. getet element byid call can actually look for an element that has the ID main okay so you again this can be literally anything you want you just need to make sure that you have that changed over here as well okay the second thing that I want to mention is this script tag over here so what happens is this so let's say for example if I were to just comment out this script tag you'll notice that nothing appears on the document in fact if you look at the uh the the browser or the the source code over here you'll see that the only thing that is being rendered to our uh browser is this div right over here and you can see the common is right over here okay we don't have our hello world being rendered out Okay the reason why that's happening is because we need this script tag so what happens here is it loads up this entry file this main. jsx file okay and these methods that are being called actually does something called client side rendering so it loads up this script file and then it's going to go ahead and you can kind of think of it as like unpacking everything it's going to go ahead and uh client side render all of your react code or all of your JavaScript that you wrote in your react components and it's going to generate those components into actual HTML elements okay I'm not really going to go super in depth into that whole process but I just wanted to mention that this entry point file is very important without it you can see that your entire react application is not going to appear in the document okay so hopefully this whole process makes sense I wanted to go in depth on this because I think understanding this is very important because it also helps uh debugging and diagnosing issues a lot more easier so in the next section of this tutorial I'm going to show you how to get started with setting up your first react component it's going to be a lot of fun so I'll see you all in that section Intro to Components in this part of our react tutorial I'm going to teach you how to create a component and render it to the document before we do that I want to show you some diagrams to help you better visualize components whenever you look at a website I'm sure many of you are just used to looking at a website as a whole but not ever thinking about the individual pieces of the website in the form of a component that eventually Build Together the final View so let's look at this first diagram that I have over here we have a navbar component which is responsible for displaying links so you can click on it and go to a different page on the application you have a posts component and it's responsibility is to display posts made by either yourself or a user imagine this is some kind of social media app okay you have a feed component or an activity feed component and this can display events that are happening such as when someone adds you as a friend when someone followed you or whenever your favorite artist made a post to their uh to their social media page it'll display all over here and then you may have a footer component that displays additional links or miscellaneous details if we wanted to narrow this down and be more specific keep in mind that a component can also render other components inside of it as well and that is known as child components okay in this next diagram you can see that I have this post group component now this this diagram is actually just a more detailed view of the previous diagram so the post group component is really just the same component as the post component they have the same responsibility of rendering posts okay now when we say render posts what we really mean is that we are rendering um multiple instances of a post itself so we're going to call that component something like post item as an example right and each post item is going to have the same Fields the same properties right for example each post item is going to have the title of the post the author of the post the date that the post was created the amount of reactions the post has etc etc okay but each post or each post item their fields will have different values right because remember each post will have different authors different reactions different creation dates you get the idea okay a better way to think of it especially if you've learned about object-oriented programming before think of it like this you have post item as a component and that component is a blueprint it describes how you are going to display or render information to the page okay it's a blueprint but keep in mind that a blueprint doesn't mean that every single uh final creation of that blueprint or every single uh derived creation of that blueprint is going to be the exact same thing right you'll have a blueprint of a house and while the house follows that blueprint the house can have different uh you know countertops it can have different floorings like some houses may have carpeting some houses may have tiles some houses may have uh hardwood I think you get the idea different houses can have different number of bathrooms it still is the same floor plan this it's following the same blueprint it just has different options and in this example we have the same post item instance it's just each post item has different information pertaining to its field again different author different number of reactions different different uh content okay you get the idea the same thing applies to our feed component again you have an activity feed that is the parent component because it renders feed item so it's the parent component of these feed item components feed item component is its own individual Blueprints and each feed item is going to be different okay so I hope that this makes sense because it's going to really help you understand how to render components and how to design components effectively one more example I want to show you is this mockup that I found on dribbble.com and you can see that this is a website that could potentially be a real e-commerce website and you can see we have our navigation bar we have our links we have this uh part over here and again as a regular user you might think of this as just a plain image but you can think of this as a promotional Banner component because its responsibility is to display a promotional Banner for the user to tell them hey this item is currently on sale buy it now and you can see that it has an image it has promotional text and it has a call to action button if you scroll down over here this is a better example that fits the uh post group and feed example that I just mentioned okay so right over here you have these individual elements that Are all uh products right you have headphones being displayed but you can think of these individual uh products as product item components okay and notice how they all have the same format they have an image they have this heart button this is known as a floating action button and this is common on e-commerce websites you can click on this button and it typically will save the item so you can view it later uh you have the title the name of the product a descrip deson the price and then the number of reviews um you have the add to card button so these product items follow the same structure it follows the same blueprint but each one of them looks different okay they all have the same templates but each instance of this product item component is going to result into something different they have different images different text different number of reviews you get the idea and then all these product items are all wrapped inside a parent component which typically we call a wrapper or a container component and it's better to show you that in the form of an example which you'll see when we actually get to rendering elements rendering arrays which is known as Dynamic rendering so hopefully this example made sense now let's go ahead and jump into the code so one important thing to understand is that one component comp are Universal to literally any library or framework on the front end that you'll use so if later on you choose to use VJs or angular well the concept of components is ingrained in your head you don't need to worry about that anymore because it's the same thing in angular and in vuejs and any other framework you just have to learn the syntax and another thing that you need to understand is that with all these Frameworks all these libraries you will always have one root component that hosts the entire structure of the application so in other words we're going to need to have one root one parent component that will hold all of the other components also known as child components so if you remember earlier we had a component called app that was being rendered we actually deleted it and the reason why we deleted it was because there was just a lot of content in that file and I didn't want to overwhelm you all so what we're going to do is I'm going to remove this div hello world and you can actually think of it like this this div right over here is in fact our own component it just renders the text hello world okay and the hello world text is actually its own child component but I'm going to go ahead and remove this and we're going to go ahead Creating a Component and create a new file we're going to recreate that Roots app component so I'm going to call it app.jsx and every single component is basically just going to be a function Okay so in order for us to create a component we need a function so I'm going to call it function app just like this and then we also need to make sure we are exporting this function because we want to import it anywhere that we want to render this component in our situation we're only going to render it once inside our main. jsx file or the entry point of our application so what I'm going to do is I'm going to export this as a default export just like this now with components yes it's a function but this function needs to return something and that something is known as jsx which I mentioned in the introduction of this tutorial but jsx stands for JavaScript XML and I did mention that it does look a lot like HTML and a lot of people mistakenly call HTML because it's so similar but it is jsx okay okay semantically yes there are differences and we're going to call it jsx throughout the entire video so we're going to use the return keyword and we're going to return some jsx so what does that look like well HTML actually is in fact valid jsx so for example if I want to use this div and then I want to go ahead and return let's say an H1 tag that says Roots component just like that this is valid jsx although it is also HTML this is also valid jsx so let's keep it simple what we're going to do now is go back to our entry point file our main. jsx file and I'm going to go ahead and import up top over here on line three I'm going to import that app component that I just created from the app file and vs code allows me to autoc complete this but I can just do this import app from app just like that so remember because this is a default export I need to make sure I'm importing it as a default import as well okay so just like this so no curly braces in this situation now what I'm going to do is in between this react. strict mode in between these Tags I'm going to go ahead and render the app component just like this it's going to look exactly like how we would how we would render an HTML element to the document so angle brackets app and I could do it like this this is the long way to actually render components and react you would only do this if you actually were going to pass a child component into the component right over here into app but we don't have a child component that we're going to pass into app at least we we're not going to do that right now for this component so what we're going to do instead of using the long syntax is we're going to shorten it by doing this so angle bracket app and then closing it like this okay so now what I'm going to do is I'm going to go ahead into my browser and you'll see now it renders this H1 tag into the document and if I open up the browser tools by just hitting control shift I or just right click and then just click on inspect or view page Source actually not view page Source sorry just click on inspect and then you'll see that right over here in the body tag right over here I see my root div with the idea of main because we changed it earlier you know let me actually change that back before I forget let me change this back over here to roots and then go over to index. HTML and change this to Roots just to be consistent but again if I expand you'll see that I have this div and this div is right over here this is the root div of my app component and this div holds my H1 tag that says Roots component right over here so there you go that is your very first component in react now obviously we're going to see a bunch of other examples but this is our root component the app component is our root component so I'll go ahead and show you some more examples with components I'll actually create a new folder called components and I'll place all of my component files in this components folder so what I'm going to do is now I'll create a new file and think about the component that you want to create you don't have to copy the exact component that I'm going to create you can be creative and try doing it on your own as well but think of any component you want to create so I want to create a component that represents a user profile so I'm going to call this component user profile and I'm going to use Pascal casing so the first letter of each word is going to be Capital so or capitalized so user the letter U is going to be capitalized and F the letter P is going to be capitalized and then end it with jsx so now what I'm going to do is I'm going to go ahead and create my user profile component so remember every single component needs to one be a function and two return jsx I'm going to keep repeating this throughout the entire part of this tutorial so that way it is ingrained in all of your heads so we need a function so we'll use the function keyword and typically you want to name your function based off of the component and in my situation I'm going to actually name it off of the file name so they all match and this is common convention so user profile is going to be the name of this function which is also going to be the name of my file and the name of my component and then remember that we also need to return jsx so return and uh you can use a div you can also not just only use a div but you can use literally any HTML tag you want you can use a section if you want to you can literally even use navbar or not Navar nav if you want to this is for navigation but let's stick to div for now and let's make sure we export this function so what I'm going to do is I'm actually going to export this as a named export because sometimes you might want to have other exports in this user profile file it doesn't just necessarily have to be one single component that you might export we only did a default export for app.jsx was because this is the root component and there's going to be no other components inside of here but you can do this as a default export if you really want to but I'm just going to leave as a named export just to show you different patterns in different use cases so again we have our div this is going to hold all of our content for our user profile and I'm just going to go ahead and use literally any HTML element that I want so I can use a paragraph tag and I'll just uh do username Bob and let's see let's do another div and let's do span tag let's do email and I'll use another span tag and then we'll do anen anen the.com just showing you some simple examples right um and let's see what else can we do I can do something like I can use a section I could even use an unordered list and let's just do something like this let's [Music] do uh let's see favorite food and then let's do a break and let's do sushi and I'll duplicate this a couple more times we'll do pizza and uh mediteranian food hopefully I spelled that right okay now that we've cre our component and return jsx and remember this is all HTML but we're going to call it jsx we're going to go ahead and now render our user profile component inside the app component because remember your app component is the root component everything is going to belong to this app component okay when we get into routing and and uh navigating users or navigating ourselves between different parts of the application you're going to see that it's actually going going to uh be inside the root application itself so let's go into uh inside this div so right underneath on line five I'm going to go ahead and first let me import my component so import and I'm going to use curly braces because I'm importing this as a named import so user profile and this is going to come from the components folder and then the user profile file and then we're going to use angle brackets to render our user profile just like this and now if I go into the Dom or the browser you'll see that my component is being rendered and if I look at the dev tools I can see that this is the div you know what let me actually go into user profile let me give this div an ID so that way we can easily detect it in the browser tools so you'll see that right now over here this div is in fact uh the user profile component and then we have all of the other HTML right over here okay so really what actually happens is we are uh writing jsx we're writing our code inside our jsx file and then when we actually render our component uh react takes care of uh generating all of this from jsx into actual real HTML and renders it into the actual virtual Dom itself okay and this is again known as client side rendering so hopefully all of this makes sense I do want to show you another way just to create components is not the actual way that you're going to create components when you're writing your react application but I did want to show it to you regardless so I'm going to go ahead and create a new file and what I'll do is I'll create a component and I'll call this uh let's do user favorite foods and we're actually going to uh show you two things at once so this is going to be a user favorite foods component and what I'm going to do is I'm actually going to uh abstract this part of the user profile so I'm going to take this section that had this unordered list and I'm going to move it into its own component and again this is something that you're going to do often in react you're going to uh take components and put them into other components so that way it makes it a lot more easier for you to manage individual createElement function components so let's go ahead and do this I'm going to go ahead and import a function from react and that function is going to be called create elements and this is actually the old way of creating components in react we don't actually do this anymore but underneath the hood react actually uses these functions to create the actual elements that gets rendered to the virtual Dom so I'm going to use this create element function function and I'm going to give the name of the function user favorite foods and then I'm going to simply just first let me export this function and then I'm going to return and then I'm going to not return jsx but I'm going to return the function call of create element just like this now create element will take a couple arguments so the first argument is going to be the type so this is going to be the type of element the type of HTM element that you want to actually create so we're going to use div so we're going to do div you can use literally anything you want you can use section you can use div whatever you want and then the second argument is optional you can see that in the intell sense it's telling you it's this second argument is known as props we're not going to talk about props right now but will get to that in just a bit we're going to leave this as empty so you can either just pass in an empty object you can do null you can do undefined whatever doesn't really matter we'll just put an empty object for now or actually no I'll do no and then the third argument and any and every other argument afterwards because this is actually all spread out because you can see over here that you can actually pass in an indefinite amount of uh arguments after the second argument so the Third third argument and every other argument afterwards is going to be children of this div element that you're creating so what that means is right over here what I can do is I can literally just pass in any valid jsx so for example if I wanted to pass in a div and say uh user favorite foods and if I save this and now what I'm going to do is let me just before deleting the section let me go ahead and render user favorite foods so I'm going to import that inside my user profile and now you can see how we are building our hierarchy so I'm going to import that and then right down over here I'm going to render user favorite foods just like this okay and then if I go into my browser you're going to see user favorite foods that text that is inside this div element and this div element is inside this div element as well is being rendered if I go over here you see we have this div which is this div and then we have this inner div right over here which is the child of our parent div hopefully that makes sense I know that kind of sounds a little bit confusing but um let me do this now what I'll do is I'll take this entire section I'm going to copy it and I'm going to just paste it literally right over here and now you're going to see if I refresh uh you're going to see that so inside the user profile component so this div right over here you can see that I have this div which is this user favorite foods component and then in that component it has this section as a child component or a child element and it has our unordered list right over here okay so visually it looks all the same but from codewise as a from the developer perspective it's actually different okay but to the user itself they're not going to notice any difference at all and one more thing that I will do is actually I don't even need this div I can actually just change this to section and I can remove this section over here okay and now what we can do instead is we can actually just put some commas uh right over here at the end of the span at the end of the BR The Brak tag and then we don't need to do it for these list items because it's all encapsulated in this unordered list but now if I refresh and I want to show you this because this is very important you're going to see that all of these elements so this span this break and this unordered list they are all part of the section okay so literally every any any element you want to pass in as an additional argument is just going to be an addition element that will be appended to this section okay so really what happens is it just adds the element to this section node right over here okay as a child node so that's why when you hover over when you actually hover over here it shows you that this children argument over here is actually an array of react uh react nodes or react elements and you can pass an indefinite amount and they'll just all basically be appended to this uh section element or whatever element it is right here hopefully that makes sense okay and you'll notice that if I actually just take this whole thing and if I put this in a div and if I remove the commas all of these elements now will actually just go inside this div so there'll be immediate child elements of the div but they will not be immediate child elements of the section hopefully that distinction makes sense okay but again um you're never going to really use create element to actually create your uh components so you don't have to worry so much about this if this is a little bit confusing uh just stick to creating your components the first way that I showed you just like this but I just figured I would show this to you all just to kind of give you all a little history lesson because this is what was how you would create components back then in very early early stages of react okay and I'm talking about like 9 10 years ago when react first came out but okay let's go ahead and move Component Props on so now what we're going to do is talk about component props in react so what exactly are props or short for properties well props are pretty much just data that you are passing in to your components and those components take in those props they can take in that data and they can do literally whatever they want with it they can use that data and render it to the document they can take that data and send it to a server by making an API call they can take that data and pass it to another component um they can take that data and concatenate it assuming it's a string or even a number they can concatenate it with another piece of string or another number they can do uh math operations such as adding that piece of data with another numeric value whatever it is you can do literally anything you want with props okay so what I'm going to do is this I'm going to go ahead and uh let me create a couple more components so I'll go ahead and create a new file I'll call this user username jsx and these are just going to be very simple components but the idea is to show you how props work so export function user username and this component's purpose is going to display the users username okay so we're going to return a div and what I'm going to do is I'm going to also make sure I prefix the username with the actual with a label or some text that indicates that this is the username so what I'm going to do is I'm going to use a span tag well actually not span I'm going to use the B tag which bolds this text okay and what I want to do is I want to render the username in this span tag right over here okay now here's the thing though how do I actually render the username itself right well this is where we need to actually pass data to this user username component so how do we do that well what we're going to do is we're going to go into our user profile component so where we are going to render our user username component so I'm going to remove this P tag right over here where I rendered this hardcoded username Bob text and I'm going to render user username just like that okay and to pass a prop to a component it's very easy all you do is in between where these angle brackets are and right after where you have your component name so after user username I'm going to go ahead and give my prop a name now if you're using typescript which since we're not using typescript you would need to actually have type annotations for your components okay which makes it very strict which is actually a good thing because that way you're not just randomly passing in random props to components that don't need that data but since we're using JavaScript I can literally pass in any prop give it any name I want but I'll show you also how to validate props later on using a package called prop types so I'm going to go ahead and give my prop name so I'm going to call it username you want to make sure you're giving your props relative names to the data that it is so for example if that data is username or if it's email you want to make sure the prop corresponds to that piece of data so username and we want to have an equal sign and we're going to be passing a string down to this user username component for this username prop so I'm going to use equal sign and I'm going to go ahead and give it the name Bob just like this and now we need to go to the actual component that is going to be receiving this prop and in order for us to actually be able to reference this username prop the way that we handle that is well this user username remember that this is a function and what's really happening is we're actually passing in this username prop as an argument to this fun function in other words when you actually render your components and react you're actually really just calling the function itself okay you're actually just calling this user username function except you're calling it by using these angle brackets tags okay when you pass in props you're actually just passing in an argument to that function so all of those props you can pass in as many props as you want all of those props are all encapsulated into an object and that object gets passed into to the component function and that argument is just called props whoops props just like that let me show you what happens if I were to console log props let's go into our browser and you'll see how over here if I go to the console which you actually may have already saw that already but if I go over here to console if I refresh the page you'll see that uh we have username Bob okay as a field or a key value here and it's in this object right over here as an example let's say if I wanted to pass in some more props so let's just pass in um let's just say uh trimmed username just as an example you'll see now both username and trimmed username are in this single props object right over here now if I wanted to reference either one of these props username or Trimm username all I have to do is just reference it by just using the dot operator so Props Dot and then the name of the field and that's always going to match the name of the prop so username username just like this now you can see right over here it is complaining because we have eslint enabled it's complaining about it missing prop validation the code should still work the applications should still run it's just that your uh vs code is just giving this yes warning your your application will work fine though but if I refresh you'll see now it is logging just Bob because I am referencing props do username if I reference props do trimmed username it's going to log Bob as well so hopefully that makes sense now we want to actually render the username to the document we're going to do that inside this inside these span tags now in order to actually render the username we know that it's coming from that props do username field which is actually a field inside the object before we rendered a username by hardcoding it to the document but this time we actually have this value that is defined in a field or you can kind of think of it as like a variable right how do we actually render that how do we actually extract that value from that field end then render it to the document we're going to do something called evaluation so for example if I reference props do username right over here this is a literal value and in the document it'll just literally render prop. username that's Evaluating Props not what we want we want to actually evaluate this object's field so that way we actually get the value itself to do that we're going to actually wrap this in between a pair of curly braces so this will evaluate this props do username field and then it'll grab us that username value so if you look at the document right now you can see that Bob is being displayed to the document because this username field was EV valuated I'm going to go ahead and remove this console log now you can pass in other data types as well you don't have to only pass in strings so just as an example let's say let's remove trimmed username uh let's do this so what don't want do this let's go into our app component the root component and we'll pass in props to user profile so let's pass in the age of the user so what I'll do is inside this div um I'm going to go ahead and do this let me remove these two span tags let me remove this div actually so I'll use uh a bold tag and I'll do age and then span and then we're going to go ahead and expect props so let me go ahead and pass that as a argument for the user profile function and then we're going to go ahead and reference props and the name of the prop will be age so Props do Ag and then remember we're evaluating that by using a pair of curly braces so now let's go into our uh app.jsx file or really any file wherever you are rendering the user profile component and then we want to pass in that age prop so since we are passing in a numeric value we need to actually use a pair of braces okay if I actually used quotation marks like I did earlier to pass in a string it would pass in this numeric value as a string so if I put 20 it would treat age it would treat that age prop as a string instead of a number and you'll see right over here if I actually rendered or not rendered console log props and if I went to my browser you'll see that it's treating the field as a string instead of a numeric value which is not what we want because you might want to do some kind of uh arithmetic and you'll have to worry about parsing it first so what we'll do is we'll use curly braces and then pass in the number 20 just like this and now if I save and go back to the browser you'll see now the number 20 doesn't have quotation marks uh in between or around it so now this is an actual numeric value so you don't have to worry about parsing it at all okay and then now if you see right over here it is rendering that prop it is rendering the age 20 just fine so that's good and then you can also pass in uh booin if you wanted to so for example let's say if I wanted to pass in uh let's say for user profile let's say we want to pass a prop called is logged in and let's set this to True okay and then then let's just evaluate the prop right now props is logged in now it's not going to actually show you anything because this is a boene so it's not even going to render the text at all but I could just do something like this where I call a function or call the string Constructor and then evaluate that so you'll see true is being rendered and I can change this to false again just showing you this as an example later on you'll learn about additional rendering so you'll see how we can use a Bine to render specific stuff to the document okay so uh that's just an example you can pass in arrays uh so let's just say for example for user profile we have favorite foods and this might be an array of favorite foods so this will be like an array of objects so let's just say uh name Sushi okay and then what you would do is you would reference the prop which you'll see right over here favorite foods whoops let me go to the console you'll see favorite foods is in fact an array and then what you would want to do is something called Dynamic rendering uh or in other words rendering lists so you would take that props dot favorite foods array and then you would iterate through it and then you would render uh basically each object as an actual renderable element which this is something that I will show you later on okay so uh yeah you can literally pass in anything you want you can pass in an object as well you can pass in um you can even pass in a function so let's say for example if I had uh call me so let's create a random function uh let's do this let's not use an alert let's just do console log hello and then let's just do uh call me let's just pass as a prop you'll see now the object props has this call me field which is a function and then you can see that it has the implementation right over here but what I could do is I could just immediately call props do call me like that and you'll see that when I refresh the page uh it console logs hello which is pretty much calling this call me function so hopefully that makes sense again you can pass in literally anything you Type Checking Props want so now I'm going to show you how to use a third-party package called prop types this is very important for type checking your component props because you can see we are able to pass in any type of prop that we want without even validating it at all and that's not good because you always want to make sure you are validating what your component is taking in as a prop and then you also want to make sure that those props are actually being passed in if a component expects one so what we'll do is we'll install this package so we're going to go into our terminal and type in npmi prop types all right let me go ahead and run my app again Perfect all right so now what we're going to do is anywhere that we have a component so let's go into user profile okay we're going to go ahead and import this package and I'm actually going to do this on the first line so we're going to import prop types like this from prop hyphen types just like that okay once we import that we can go ahead and take our user profile function so user profile Dot and then you can basically dynamically attach this property prop types just like this to your function itself okay so user profile. propop types and then inside this object over here you want to basically Define the props that this component is expecting so for example this component right over here expects uh currently only one prop but you know what I'll do is I'll actually do this uh I'm going to take this username prop uh let's do this let's go back to app I'm going to pass in a username to user profile so let's just do Bob and we're going to this is known as prop drilling by the way we're going to take the prop that we passed from the app component to user profile we're going to take that prop and then pass it to user username component so Props do username just like this okay so I'm basically taking the prop uh that was passed to user profile and then passing it down one more layer to its child component user username and you can definitely do this okay so we have so far uh I guess three props so let's go ahead and go back to our prop types object so the first one that we'll handle is username so we'll Define the prop name so username just like this and you'll notice how as soon as I type username this lint ER this lint error goes away okay so what we want to do is set the data type for username so we'll do prop types so we're referencing the prop types import from up top over here and then we're going to do do string so this basically tells uh JavaScript as well as react that okay this username prop is a string and then we can additionally also make this prop mandatory by adding this is required at the end so do string do is required so it's pretty much chainable if think about it like if you think of it like this it's kind of like you're calling um a method and then that method returns um the same instance that that method was called on and then you can basically call the same method again so in this situation we can call or not call but reference string and then reference is required and then uh there's really nothing else to reference anymore after that but um yeah you get the idea so now watch what happens when I go to the browser let me go ahead [Music] and open up the dev tools okay so watch what happens if I do this let's say if I go back to app.jsx and if I don't pass an username and if I go into the browser if I refresh you're going to see that it gives us a warning the application doesn't break but it gives us a warning and it says failed prop type the prop username is marked as required in user profile but its value is undefined so this is basically telling you that you need to make sure you pass in the prop for username so this is good because if we don't pass in a prop for something that is required then it's going to complain and notice how if I were to pass in anything but a string so if I pass in an array whoops let's go back to the browser you're going to see uh right over here it gives us a warning a failed prop type invalid prop username of type array supplied to user profile expected string let's go ahead and pass Bob back and that should fix everything so no more warnings good let's go ahead and type I shouldn't say type annotate I was going to say type annotate because I'm used to typescript let's go ahead and add prop or type checks for the other props so let's go ahead and type check age so we'll do age and we'll do prop types so this is going to be a number so there is is number right over here and then we'll do is required and then we'll do the same thing for this call me function so we'll do call me prop types Dot and then there's this funk property and then we'll do uh let's see is required just like that okay so now we are making sure that username age and call me all are being passed as prop okay so these are all required now what if you wanted to have a prop that was optional well you can do that so let's say for example let's say this is logged in prop okay let's go ahead and add this so is logged in we'll do prop types the type of this is going to be a bull or boene so they have bull and then uh if you don't want it to be required in other words if you want be optional then you just omit this is required uh right over here so you don't add is required okay you leave that out so now if I were to not pass is logged in as a prop if I go back to the browser you'll see that we don't have any errors but if I were to add is required at the end you'll see that now it complains about the is logged in prop because it is required so hopefully that makes sense okay now you can also check the props for arrays as well so right over here I have this favorite foods prop and this is an array and let's say I want to make sure that this array has consistent values okay so for this example right over here I have an array of objects let's add a few more objects and let me also add another property let me give this an ID and let me capitalize this and let me do the same thing down here so let's do pizza and ID okay and I want to make sure that this array has consistent objects so in other words I don't want this array to just have a bunch of random elements in there I don't want this array to have a mix of numbers strings blein objects I want it to have only objects and I also want each object to be the same and have the same Fields so what I can do is I can go back to my user profile and down over here I can add a check for favorite foods so favorite foods like this and then we'll reference prop types and what I want to do here is I want to reference array of not array but array of okay if you have an array that you're passing as a prop that just has literally anything you want and you only care that it's onr you don't care of what the contents look like then you would use array so in other words let's say if you're just passing in an array and it has a number it has a string it has an object then you could just use array okay array is good for just checking to see if the prop is an array not for checking to see if the contents of the array is valid or not so in our situation we want to use array of and then this time over here I'm going to actually pass in prop types. shape because we want we care for the shape of our object over here so prop types. shape allows us to check for a specific object and making sure that that object has a specific shape okay so we're basically combining two things together so now what I'm going to do inside when I call shape is I'm just going to pass an object and then I can do the same thing that I've been doing up top over here for these four fields for the fields for the object so I'm going to specify name and then prop types. string. is required and then same thing for uh ID prop types whoops prop types string is required just like this okay it can look a little bit complex but just know that what we're really doing is one we're validating the object right over here that is inside the favorite foods array and then we're making sure sure that this favorite foods array is an array of all of these objects that have this shape okay so hopefully that makes sense so now what I'll do is this so if I go to the browser Let me refresh you'll see that we have no errors but notice what happens if one let's just say if I pass in an object you'll see that it complains because it is expecting an array right over here it's saying that it expected an array if I pass in an array this works but let's say if I pass in an array with an empty object you'll see that it now complains because although we do have an array with an object with one element that's an object that object is empty but that object does not take in the correct shape you can see that over here that the shape of the object does not have the name property that is required okay now now let's say if I add the name property it's now going to complain saying that the ID is not there okay so we need the entire thing so let me go ahead and paste that back here and now the errors are all gone but notice how if I remove ID from Just One of the objects it's going to go ahead and complain and also tells you the specific index of the uh array that it is having an issue with so in this case you can see it says index one so that's this element over here okay so now you know how to validate uh arrays as well as validating the specific object for the array itself so hopefully all of this makes Children Components sense now one thing that I want to quickly mention with our components is that we actually have a parent to child relationship and we also have sibling components as well so let me emphasize a little bit about that because this is actually very important concept to understand when it comes to developing really any application okay if you understand objectoriented programming this is something that should uh come easy to you so right now we have our root component we have app now app has one child component that we are rendering called user profile the moment that you render a component inside another component which is what we're doing right over here that immediately creates a parent to child and child to parent relationship okay between for for components so app has user profile okay if we go into the user profile component we can see that user profile also has components being rendered as well we have two components being rendered inside user profile okay if I take away user profile if I don't render user profile that means that user user username as well as user favorite foods these components that are being rendered inside user profile will not exist in the document itself unless if I explicitly rendered those two components directly inside the app component okay so user profile also has child components as well it has user username as well as user favorite foods so that makes user profile the parent of these two components and these two components are children of the user profile component okay and of course the hierarchy can go down infinite amount of times if user username had any child components being rendered then those child components would be children of user username and that would make user username a parent component okay now because user username as well as user favorite foods component share the same parents user profile this automatically makes them sibling components the nice thing with sibling components is that you can share the same props that were passed to its parents so for for example all of these props username age favorite foods and this call me function that I am passing down to the user profile component all these props can be passed to both user username and user favorite foods allowing me to share those props between these two siblings now that's useful because sometimes we may want to share very similar props between different components maybe user favorite foods needs the username as well as the user username component so we may want to consider passing the username prop to the user favorite foods component as well okay so hopefully this makes sense later on you'll see more examples where when we work with State you'll see how when I update one state variable you'll see how it will reflect all of the child components and The Sibling components as well okay and then I'll also show you how I can update data from a child component and have that reflect the parent component as well okay but I just wanted to go over this very quickly because it is something very important to understand in react but we'll dive deeper into this when we get into working with with Fragments State now one more thing with components that I wanted to talk about are react fragments this is actually something very very important to understand in react and knowing when to use it is actually very very beneficial for your situation so right now all of our components have one root element that we are returning remember what I said a component is a function that returns a jsx element or Js B expression in this situation we're returning a div and this div can have as many HTML elements as we want however if I remove this div right over here you see that it actually errors out and it's complaining saying that we must have one parent element that's because by default I can't just return two HTML elements just like this okay now you might be wondering well maybe you might want this bold element as well as a span element to be rendered to the document and uh let's say for example this user username component is being rendered inside user profile you might want these two elements to be immediate children of uh wherever this component is being rendered so it's being rendered right over here so you want those two elements to be immediate child elements of this div right over here okay now how can I achieve that without needing to write wrap them inside a div right because the moment that I wrap it inside a div it becomes a child element of the div now it still technically is a child element of the root div the outer div that where wherever it's being rendered but sometimes having these elements being wrapped inside a another element can break CSS or it can break your selectors for example you might have specific selectors that you're using that need to Target IM immediate child elements okay so I'm just using that as an example so what we can do to add these two elements to the document without needing to add this div is use a fragment and it's actually very easy to use so there's two ways that you can use a fragment syntactically so the first way is you can do it like this you can reference react. fragment just like this whoops fragment and then you want to make sure you close that as well right over here okay we do need to import react up top over here so import react from react okay and now notice what happens in the Dom tree so if I were to go back to my browser and if I expand the HTML elements you'll see now we have both of our elements that are from user username component and they don't have that root root div anymore and they're immediate children of its parent components root element also known as uh the user profile component okay they become immediate child elements of this uh div with this user profile ID okay you can see that right over here if I remove this react fragment and if I change it back to a div you can see that that div gets added to the document and it's wrapping both this bold element as well as this span element right over here okay and again there's no right or wrong answer it's really up to you on how you want to structure your HTML remember there's no right or wrong answer with HTML and CSS it's how you want to structure things I'm only showing you this because you might have certain needs that might make it so that you don't want this div to actually be added to the document because of styling issues or maybe you might have specific selectors that you need to Target get uh this bold element as an example and you cannot have this div right over there okay so using a fragment would solve that issue now the shorthand way to use fragments is actually instead of just using react. fragment you just use an empty tag just like this okay so you literally just do angle brackets you don't put anything in between and then you close it just like this so angle brackets and then put a forward slash and then you're done and that's literally a fragment a Shand Syntax for fragments and it does the same exact thing okay if I were to go into user profile I can literally remove this div right over here and wrap all of these elements all of my components and elements in a fragment and if you see right over here now all of these elements are immediate uh children of this div and that div is this div right over here which is the root element of app okay since user profile is the only component that I am rendering I can actually just remove this div and now we can see that all of uh these elements are immediate child elements of the root div which comes from our entry point right over here okay so hopefully fragments make sense and again there are many different ways that you can use fragments like I said you can use the group components together so if I wanted to just render uh let's say for example I want to render user username with user favorite foods together I can group some I can group them together just like this with a fragment and I don't need to worry about adding an extra HTML node to the document not that this would really change anything in terms of your tree structure for your uh for your application but um it is a way to group stuff together so I just wanted to mention that okay because sometimes like I said you want to group elements together you want them to be all grouped together but you don't want them to be wrapped inside a div because that div could uh let's say uh put them all in the same row or maybe it might put them all in the same line whatever is it could break CSS so using a fragment could help in some situations again this all primarily depends on how you structure your CSS so you have to make sure you understand okay what exactly is my CSS targeting and should I use a fragment for this to achieve what I want to do so hopefully react fragments make Styling with CSS & SCSS sense all right so now we're going to go ahead and talk a little bit about styling in react so this is just going to be a short little section we're not going to go in depth on CSS because this is not a CSS tutorial but I did want to show you how to at least style your react application as well as style components so we're going to start off with some basic CSS files so what we'll do is we'll apply what's called a global style so a global style basically just means that you want to apply your Styles globally throughout your entire application so literally everywhere so in other words let's say for example I want to apply a global background maybe I want to apply a dark color background everywhere throughout the application so how would I do that well in order to apply a global style we want to make sure that we have first a CSS file so I'll create one uh let's create a new file we'll call this global. CSS okay and this is where all of my Global CSS will be defined so uh what I want is I want to make sure I have a dark background color so what I'll do is this we'll start off with a body tag and then we'll do background color and then let's do uh let's start with 0000 and I'm going to use this VSS code feature to kind of like change the background color so I'm going to use 1 e 1e 1e and then I also want to change the text color to be I guess white maybe not white but just like a slight light color so that way we can actually see the text and now to apply the CSS to our actual application because right now it's not being applied what we need to do is we need to go to our entry point of our application and we just want to import that global. CSS file just like this and now you'll see that the CSS is being applied to our application we basically inverted the colors we made the text white and we made the background dark okay so that's how you can apply Global CSS so this is I would recommend you set things such as the font family so if you wanted to set a font family you could do that right over here so let's say if I wanted to set it to I don't know um sand serif maybe I don't maybe I don't have that font oh right there okay there we go the font just changed okay uh if you want it to set let's say uh you can also set like a height as well set the height to 100% and B basically any uh any Global CSS you want to put inside this file okay let's talk about component level CSS because obviously we have our Global CSS but then we have our components where we want specific CSS applied to it okay so let's say for example maybe for my let's do user username okay let's say for this user username component I want specific CSS applied to uh the font to the color the text whatever it is right I want to make sure that I'm applying it only to this component and not globally throughout the entire application okay so what I want to do is this there's two ways that I can do this one I could just do an inline style so I'll show you how to do that so let's say if I wanted to change the font size of this uh of this username text I can just go to the tag itself and I can do style and then equal sign and then you want to provide a pair of curly braces so with inline styling in react it's way different than how you would write it in just regular HTML so in react you want to actually pass an object into this object over here or into this pair of curly braces right over here just like that and basically this object will have all of these CSS properties so for example if you wanted to apply the font size you would just do font size and it could pass in the string so let's do 32 and now if I go to the document you can see that let me just make sure I'm not zoomed in oh I was zoomed in let me see let's change this to oh it should be 32 pixels sorry about that so now I can see that it is being applied to the username text and if I look in the dev tools you'll see that this uh this B tag right over here has this style attribute and then it has font size so again this is how it would look like in HTML but in react you want to make sure that you applying it inside this object right over here if I want to change the color I would just do color and then I want to set it to let's say uh maybe a red color like that and then that would be applied right over there okay so that's how you do it in line uh let's show you a couple more examples there's also let's see um there's font size font family maybe you don't like the default font that we set globally so you can do something like cursive and then I'll change right over there okay there are a bunch again you can just go through intellisense and look through all the other ones um but if there's one that you want and you know the name of it just remember that it's the same name as it is in just a regular HTML attribute you just need to make sure that you're using a camel case so notice how in HTML right you have uh let me show you you have font hyphen size that's how you would write it in just regular plain HTML but in react or in jsx you would write fonts and then capital S size and no space or no hyphen at all just like this okay and then you want to make sure it's inside the object so hopefully that makes sense so now let me show you how to do it not with in line but at the component layer with an actual CSS file so what we're going to do is inside our components folder I'll create a new file and I'll call it styles.css and what I'm going to do here is just create a class so I'll call it username and I'll just give it the same Styles and remember this is a regular CSS file so you're just going to write CSS regularly so instead of font size like this where we did that in the jsx we're just going to do font pyth and size and 32 pixels set the color to Red now we're going to go back to our user username component and then here I want to import this styles. CSS file that I just created so we're going to import it like this import pair of quotation marks and then the relative path styles.css and then if you look in in the browser nothing has changed so far with the username and that's because we need to make sure we apply the class name to uh whichever tag we're trying to style okay it's exactly the same way that you would do it in just plain HTML so I want to style this uh bold tag this B tag so I'm going to give it a class name so we're going to use this class name attribute in regular HTML it's just class but in jsx it's class name okay and this is where you're starting to realize the differences between htl and jsx even though again 95% of it will look identical there are still a lot of things that are different actually I I should say 90% so we're going to do class name equals and then now just the name of the class so the name of the class is username so we'll just do username just like this if I save you're going to see now we see the style is being applied to username it has a fun font size of 32 pixels and then the color is red and you can even look in the dev tools we should see this right over here so this element this bold element has a class called username and when I click on this you can see all the styles that are applied to it okay now one more thing that I do also want to mention too is even if I were to let's say go into this styles.css file and let's say if I uh modify the body CSS okay so let's say if I do body and then background color let's do uh let's do Aqua okay if I refresh you'll see that it actually does not get applied to the actual document itself now I want to show you as well right over here if I go to body you'll see that in the dev tools it actually shows uh two body tag Styles okay and this one right over here is actually just being ignored you can see it's it has this line struck through this one over here just means it's being ignored because we have this one overriding it basically okay if I were to remove this background color style okay and sometimes you do need to make sure you refresh as well because it doesn't actually reflect properly but this time I can see that it is properly being reflected you can see over here that I am setting the background color to Aqua because in the global Z CSS file my root CSS file I am not setting that CSS style in the body tag okay but since I said over here it's not going to overwrite it I could overwrite if I wanted to by just using the uh exclamation mark important and then now you can see that it is being overridden okay so hopefully this makes sense I do also want want to show you one more way on how you can write CSS as well as style your components using CSS modules okay and CSS modules are actually very very common a lot of people actually like using CSS modules because they're more a prone to uh less issues when it comes to styling your components because one they are locally scoped to the component okay so here's what we're going to do I'm going to go ahead and rename styles.css to styles. module. CSS and instead of importing it like this I'm going to go ahead and actually import it like this we'll do import and we're going to give it a name so import Styles and then from and then the relative path styles. module. CSS now what I'm going to do is instead of actually just passing in the class name at as an actual uh string we're actually going to use a pair of curly braces and then we're going to reference Styles as if it was an actual object and then reference username as if it was a field on that object okay so what what really happens is this Styles this CSS module basically takes all of your fields and then it kind of like just puts them in an object and you can reference it as an actual property itself and then use that to apply the correct class to the element okay so I'm going to save and Let me refresh and you'll see now if I go to here you can see I have my B element right over here my bold element and you can see the class name is not exactly username but it has like this underscore username and then some autogenerated text right over here or this hash okay so it's not the exact class name but it is uh applying the correct CSS styling which is what we want okay and this is what a lot of people prefer to use when it comes to styling because one it's again locally scoped so you don't have to really worry about your CSS conflicting with other components now many of you may be familiar with a CSS preprocessor called SAS now there are plenty of CSS pre-processors out there but SAS is one of the most popular ones so I'll show you how to actually use it it's actually very easy um so what we want to do is go into our project terminal so in the directory I'm going to go ahead and install the pre-processor so you need to make sure you install the pre-processor before you can actually use it so since we're using vit it actually supports uh SAS out of the box or scss um if you're trying to use a different pre-processor definitely make sure you check the V docs first to see if it supports out the box and see if there needs to be any special configuration so I'm going to type npmi hyphen D and then SAS just like that okay there we go and then let's just run our project again now what I can do is create an sc CSS file so I'll just create a new file I'll call this a users. module. sccss you don't have to use uh CSS or scss modules you can just use um just a regular CSS file it depends on what you prefer not Everyone likes to use CSS modules or scss modules some people just prefer using a regular stylesheet and then importing that and then using the class name as a string literal it's up to you that's why I'm showing you all these different examples so inside um my scss file I'll just write regular CSS I'm not going to go in depth on uh using SAS but I'll just do uh let's do this let's see what else can I style um maybe I'll style uh favorite foods so uh Foods title and let's do font weight bold then font size 64 pixels just as an example and uh since I'm using a CSS module I don't want to have hyphens in my uh in my class name so actually I'm going to use camela case for the class name since I am using a CSS module okay so we'll go to let's go to user favorite foods so here I want to style this text this span element so I'm going to first import my scss module so import users I'll just call it styles from users. module. scss and then I'm going to go ahead and add the class name attribute and then I'm going to provide a pair of curly braces so class name equals curly braces and inside Styles Dot and then the name of the class so foods and then title just like that so Foods title and then now we should see it is being applied properly now if you do prefer to use a kebab case which is what this is known as where you have this hyphen in between each word you could use Kebab case but do note that uh you will need to use square bracket notation to access the class so you would have to do something like this Styles and then square bracket and then Foods title just like that okay it's up to you on what you prefer to do do I personally don't like using um square bracket notation to access properties sometimes you may need to especially if you're using Kabab case it's totally up to you but um hopefully this all makes sense so yes you can use SAS and any CSS pre- processor that you choose Dynamic Rendering Lists/Arrays to in this section of our react tutorial I'm going to teach you how we can take an array of elements or a list of el elements I'm going to use those two terms interchangeably and I'm going to teach you how you can transform each element from a regular plain Json object to a jsx element so that way it is actually renderable to the document it's important to understand this part because when you have an array of Json objects which you're going to a lot of times especially if you're fetching data from an API you cannot just take that plain Json object and plug it into your jsx code and have it render to the browser doesn't work that way because the browser needs to be able to render something that's renderable and a plain Json object cannot just be rendered to the document as is you need to take it and then transform it into a jsx element okay so I'm going to teach you how to do that we're not going to be fetching data from an API but later on you will learn how to do that and you'll be able to apply what you're learning in this section with fetching data from an API now I did went ahead and actually cleaned up our code a little bit I deleted a lot of the previous code that we wrote In fact deleted everything and I'm going to create a mock array so I'll do that right now so cons uh mock users and this will be an array and what I'll do is inside this array we're going to go ahead and just create some plain Json op objects so this is going to represent a user an array of users so I'll just give it an ID of one and then I'll give it a username and let's just do email address we'll keep it very simple okay and then I'll uh I'll do one more so we'll have two users and then we'll do uh username Michael and then we'll do Michael Michel or for email do Michael an.com so now I have two users and again pretend like this data is coming from an API okay even though right now it is mock data it is local data but pretend it's coming from an API because realistically when you fetch your data from an API this is what it could look like okay if especially if you're fetching an endpoint that returns multiple elements so if you if you're fetching an endpoint that gets you let's say 10 users at a time then you will have an array of users okay so what we're going to do is we want to render all of these users to our document okay because right now if I try to just uh let's say if I try to do this if I try to do mock users just like this right and if I go to my browser nothing's going to happen uh let me just make sure app is being rendered it is okay nothing is going to happen you're you're seeing I'm trying to evaluate this array and the browser is clearly not showing anything and you'll see that right over here in the in the logs uh let me actually refresh okay so we have a bunch of errors and it's saying that objects are not valid as a react child okay and that should make sense because right now we're working with an object mock user which is an array which is also an object and then inside this array we have plain Json object as well so we can't render this as is and that's the reason why it was giving us all of those errors so now in order for us to render all of these objects to the document we need to take our mock users array go through each elements and transform each element from a plain Json object to a jsx element which is something that is renderable to the browser to the document and the easiest way to do this is to use a prototype function on our array called array. map so if you look over here we have our mock user array I can actually call this map function right over here and some of you may be familiar with this map function already if you are that's great if you're not I'll explain briefly what exactly this function does so basically this map function can be called on an array and it applies a transformation on all the elements in that array and it returns a new array with each element transformed okay so it's just better if I just show you an example instead of just you know just saying a bunch of things so what I'll do is I'll go into the node shell right over here and what I'll do is I'll Define an array right now so I'll just call this numbers and then we'll do uh 1 2 3 4 5 just like this okay so I have an array as you can see over here and I have five elements all numbers what I want to do is I want to take each element in this array and I want to multiply each uh well actually let me say it like this I want this array to have each element multiplied by five okay so I want it to uh I want each element to be uh let's say for example for one will be five two will be 10 3 will be 15 4 will be 20 5 will be 25 and Etc okay so I'm going to go ahead and reference numbers and I'm going to call this map function now this map function is going to take in an argument which is a callback function okay and you should be familiar with callback functions you can also call this a transformation function okay so if I use uh both those terms interchangeably just know that I mean the same thing okay so this callback function is a transformation function and the reason why it's called a transformation function is because one this callback function takes in it takes up to three arguments the first argument is going to be the element of the array the current element of the array that we that we are trying to transform okay so what really happens underneath the hood when you call map is it actually iterates it Loops through all of the elements in the array every single element is going to be processed okay so the first iteration um the argument numb will be one the second iteration the argument numb will be two and so on and so forth okay so we're going to take that element that is in the array which is given to us the argument numb and what we want to do is we want to take this argument and I want to multiply it by five and you don't have to multiply by five you can literally apply any transformation you want you can add one you can divide you can divide it by let's say uh let's say 10 you can uh subtract you can do anything you want you can even parse to a string if you wanted to basically anything okay what I'll do is I'll multiply by five just like this and this value this new value so num * 5 will be returned okay and what happens is this new value will be returned um and it will be appended to a new array because it doesn't modify the original array itself okay so it will be appended to a new array and then if I hit enter you're going to see right over here that I actually get a new array outputed to our a console and you'll see that every element in the numbers array is now multiplied by five and the one thing to note is that the original array itself is not modified so this map function is immutable and what that means is just basically doesn't modify the original array itself or the original value itself so it creates a new array with all the transformed values okay so hopefully this makes sense and there are plenty of examples that you can see online as well I really encourage you to uh look up this array. map prototype function and really understand it as best as you can because if you don't you're going to have a hard time continuing with react because you're going to be using this uh array.map function literally all the time okay so hopefully this makes sense so now what I'm going to do is I'm going to go back to my code and I'm going to uh again call mock users. map so we're calling this map function and remember that we want to uh pass in a callback function aka the transformation function so I'll do that right now so this is my callback function and remember the Callback function takes up to three arguments the first argument is going to be the current element that we are trying to process so in this case I'm going to call it user because it represents the user object itself so inside uh this callback function right over here I can reference user user uh and all of its properties so I can reference ID email uh username any any field I want okay and you can see intellisense was was picking up those uh Fields but what I want to do is I want to make sure that I am returning a value you always want to make sure that you are returning a value because if you don't if you don't return an explicit value by default array. map will just return an undefined value okay so what we want to do is we want to return jsx okay because whatever you return is basically what is going to be uh returned into that new array so we want to return jsx so what I want to do here is I want to basically have uh something that is valid jsx and that could be you know a component it could be uh HTML anything okay so I'm going to go ahead and just return to div just to keep things simple and what I'm going to do is I'm going to take each uh field in the user object and I'm going to Output it to uh the Dom by evaluating each field so for example let me do this I'm going to go ahead and use a bold tag and I'm going to render the username like this so I'm going to reference user. username okay and then I'm going to use a a Break Tag so I can go on the next line and I'll do the same thing for email and I'm going to do user email just like that okay and I'll actually do one more for the ID so I'll do that before the username so ID and then span user. ID just like this oh let me also make sure I have the Break Tag as well whoops okay let me also do the same thing for down here okay right now we have a bunch of red squiggly lines a bunch of uh linting issues I'll address this in just a bit don't worry about it for now but I want to show you what happens if I go to the document and you'll see now if I refresh you can see that we are now displaying all of that data in the document okay so just to kind of like recap What's happen happening we're basically transforming each Json object that is a user to a jsx element because we're returning basically this jsx element that is renderable okay and it's just a plain div right over here and remember that we can render divs to the document itself okay so what happens is we are transforming this mock users array of objects to an array of jsx elements and in fact if I actually did this let me do this if I were to console log this whole thing right over here and if I go to the browser the browser tools and if I were to expand this you'll see that the elements are now an array of uh react elements you can see the type of is this symbol react. element Okay so it's no longer a plain Json object it's an actual react element okay and the react will take care of going through each uh element inside this array and uh taking that j6 element and rendering it to the document so you don't so it takes care of that part for you you just need to make sure that it is an element that is renderable okay so hopefully this makes sense so let me go ahead and uh just copy this and remove this console log I want to go back to addressing this issue where we have this uh linting issue right over here so it's telling us that we're missing a key prop for the elements in iterator and you're probably wondering what does this even mean okay so whenever you are dealing with rendering lists or arrays of elements to the document so right over here this is what we're doing we're trying to render an array of users we need to associate each element that is being rendered to the document with a unique value okay so in this situation right over here you can see that we are mapping this mock users array okay we're taking a total of two users transforming those users from a plain Json object to a jsx element which in the end it gets rendered to the document and we see two divs that are added to our document if I go to the browser if I were to uh go to elements and let me just kind of expand the tree right over here you'll see that we have a total of uh two divs right here we have this div and then we have this div right over here we have two divs total okay and you can definitely assume that if we had let's say 10 users then you'd be correct that there would be 10 extra divs or I'm sorry not 10 extra divs 10 divs total added to the document all of which represent a user element now we need to make sure that each one of these divs and it's not just a div it whatever your root element is so for example if this was a section uh if this was a section if this was a nav if this was any HTM element or even a component which I'll show you how to do that in the next part you need to make sure that this element has a unique key the reason why this is important is be is because react needs to use these keys to keep track of how these elements are being appended to the document as well as being removed from the document now you know in if your application is very simple you might not really notice much of a difference or you might not even notice the issue right away or at all but down the road as your application gets more complex you're going to run into weird bugs where let's say for example if you try to remove an element and then add the same element back again you're going to see that the order is going to look very weird Okay so that's just one example of a potential problem that you might run into there are a lot of other issues too that could happen so it's very important that you have an Associated key with your elements it's very easy to do that what you do is you just use this key prop right over here or this attribute we're going to call an attribute because we're just using a regular div so you're going to pass pass in this key and then you want to make sure you pass in an actual unique value okay so what you want to do is look at your resource and you want to ask yourself okay what field can I use that is actually guaranteed to be unique so for example I have this ID field and majority of time you can always make this assumption that this ID is guaranteed to be unique especially if you're using a database and your database is auto incrementing your unique IDs so it goes from 1 2 3 4 5 6 7 8 9 10 and so on and so forth you can assume that this ID will always be unique okay there might be some situations where you might not have a unique key or a unique ID that you can use and in those situations you might want to generate some kind of hash we're not going to talk about that in this section okay but for now we'll keep things simple and we know that this ID is going to be unique so what we're going to do is we're going to pass in user ID as a value for this key attribute and now you'll see that this error goes away or this warning goes away and if I go back to the browser all of my errors are gone or all of my warnings are gone okay and Visually you're not going to notice any difference at all and even if you inspect your uh your browser tools if you go into the tree what I'll do is inside uh the browser tools right over here I'm going to go to this div and then I'm going to highlight it and if I go to properties you're going to see that right over here that this react fiber property over here you'll see that it has this key and the value of it is one if I go to the next div right over here this one okay same user element and if I were to look at the properties you'll see that the key is two okay if I were to add more users so let me do this real quick I'll just add two more users I'll change the ID to three and four respectively you'll see that the other divs right over here will have a key of three and then this one will have a key of four okay and underneath the hood react will use these keys to keep track of each element again there's a lot of reasons why you need keys we'll probably dive into this topic uh in a separate video but just again remember that you always need to make sure you are assigning keys that are unique whenever you are rendering lists of elements okay and just to show you what happens if I were to have let's say two elements with the same ID you're going to see that react is actually going to complain it's it's going to say encounter two children with the same key for and it says Keys should be unique so that components maintain their identity across updates and this should make sense because again when you're trying to add or remove elements react needs to know which element that needs to remove or ADD and having the same key is going to create conflict okay so now instead of actually just returning a div and then having all of this uh jsx inside this div over here here we're actually going to move all of this code into its own components okay and this will teach you the basics of reusability while this does work we want to make sure that we're keeping our code more organized and clean and more readable okay and the purpose of this is because for example yes this does work we're rendering all of the data to the document but we always want to make sure that we are creating components that represent the resource that we are trying to render to the document okay so what we'll do is instead of rendering or instead of just returning this div I'm actually just going to return this user details component which we're going to build out so let me do this I'm going to just copy this right over here and I'll delete this div over here and what I'll do is I'll go into the user details component and instead of returning this fragment I'm going to return to div and let me paste all of this code that I just copied from right over here so it's going to look pretty much the same thing as what we had before the only difference is that it's encapsulated in its own component in its own user details component Okay now what's important is that inside this user details component you can see that we need a reference to the user's ID the user's username as well the user's email so this should spark the idea that we want to make sure that we are passing those fields as props to the user details component okay so now what we're going to do is we're going to return user details just like this okay so return user details with the angle brackets and then we need to make sure that we're still passing in a key so let's passing that key and we're going to use user. ID and let me just fix this real quick let me just change this from ID 4 to 3 and uh now we need to also make sure oh whoops I need to import the component up top over here let's do that import user details from the user details file okay so let's also make sure that we're passing in the necessary props so what I'm going to do is I'm going to pass in this user argument that we're we're getting from the Callback function that we passed to the map function remember this user argument is the uh user itself in this mock users element we're going to take that user and we're just going to pass it as a prop to user details okay so we're passing the user object into the user details component so let's do that so user we're going to call the prop user and then we're just going to pass in user just like that okay so we're passing an object to user details now we're going to go into the user details component and we need to take in the props as an argument so we're going to add props as an argument to this function right over here and now props is an object that's going to have this user prop as a field so if I were to conso log props like this you'll see that when I refresh uh you'll see that right over here on line two which is where we are logging the props over here it has this user field and that user field is an object with all of its Fields okay so what I'm going to do is I could do a lot of things I can either just reference props directly and then just reference user. ID for everything and this would work just fine and you'll see that everything is going to be rendered to the document just fine we're getting these linting issues because we have hav't done prop validation but this works just fine or the other thing that you could do and I recommend doing this is actually just destructure the prop itself in the uh argument signature so what I can do is instead of just doing props do user for everything I could actually just destructure it like this so I'm basically unpacking the user field from the props object in the functions argument signature right over here okay and then what I can do is I can reference user directly like this instead of having to reference props do user and then it works the same exact way okay now let's go ahead and just very quickly add the prop validation might as well so now you can see that we're pretty much taking everything that we've learned from the previous sections and we're putting everything together so let's add prop validation so we'll do user details. propop types and remember P right over here is a lowercase and then we need to validate the prop itself which is user remember we're only passing in one prop to the user details component we're not passing in each uh element or each uh field in the user object individually you could if you wanted to I think it's just easier just to pass the entire object as a whole okay so we'll reference user just like that and then we're going to reference prop types and then we're going to use the shape function to validate the shape of this user object so this is how you can actually validate objects okay so we need to make sure we validate the ID so ID is going to be a number so we'll do prop types. number is required username needs to be validated so we'll do prop types username is a string and then is required and we'll do the same thing for email so email prop types do string is required okay and now you can see that the linting error linting errors go away if I refresh no errors in the console no warnings in the console and if I were to remove email from one of these objects you'll see that uh it's going to go ahead and give us a warning because one of our objects in the mock user array did not have an email field to find okay and that's the reason why it's giving us this failed prop type warning so hopefully this makes sense so now you you can see this is a lot more cleaner than what we had originally you're encapsulating everything in a single component and what's nice is that let's say for example um you might not necessarily uh render an array of jsx elements to the document but you might want to render an individ idual user to the document itself and having this user details component allows you to reuse this component because all you need to do is just get the user an individual user and you can fetch that from your API right assuming that you have an endpoint that retrieves a single user you can pass in the user object and then render all of these details to the page or to the document itself okay so this allows you to reuse this component over and over and over again so you save a lot of time from just you know manually rendering a div and writing out all of these tags and you know rendering each uh field so hopefully this makes sense okay and other things that I would mention too is that this enables you to properly encapsulate uh State especially when you need state for your components we haven't talked about State just yet but we will get to that later on in this tutorial but it's just something something to Conditional Rendering consider in this section of our react tutorial I'm going to teach you how to perform conditional rendering now the term itself should give you an idea of what exactly it is you should already know what conditions are in programming but essentially whenever you are rendering elements to the document you want to often times control what the user sees based on some condition and that condition can literally be anything it can be if one is equal to one if one is not equal to one it can be if the user is logged in a common use case in the real world is checking to see if the user is authenticated and if they are you may redirect them to their personalized dashboard if they're not logged in then you don't want to render to them or give them access to certain pages or components that are supposed to be protected so in that situation you would want to render either let's say a login form to have them log into their existing account or a registration form to create a new account so this is a common example of conditional rendering working on the frontend side there's a lot of use cases with conditional rendering so maybe you want to conditionally render a banner on your marketing website to display a coupon for new users only okay and oftentimes websites will use cookies to check to see if the user has visited the website before or not so if the user has never been on the website then they'll check to see if that cookie exists and if it has a value and if there is no cookie then that means the user has visited for the first time or they may have just cleared the browser cookies in that situation you would want to conditionally render a special Banner that gives them a coupon let's say 10% off of whatever product it is that you're selling so that's that's just another example of using conditional rendering I'm sure many of you will be able to come up with a bunch of different ideas when it comes to rendering elements to the document based on some condition so enough talking let's go ahead and actually take a look at some examples so inside my main app component what I'll do just to start off with a very basic example I'll go ahead and display a message conditionally to the user based on their authentication status so we're going to create a fake variable called is authenticated I spelled that wrong authenticated I'm going to set this to true and what I'm going to do is I'm going to write a conditional statement to check the value of is authenticated and the first way that I'm going to show you is going to be a very easy way where we use an if else statement and then the second way that I'll show you we're going to use a Turner operator which is actually more common so what I'll do is I'll use a regular IFL statement so if and I'll check my condition so is authenticated okay so if is authenticated if it's true then it's going to execute this block of code inside this curly brace so all we want to do is just return jsx so again you should already be familiar with returning jsx in your component the only difference here is that we are conditionally returning specific jsx based on whatever the value of our variable is is authenticated is so I'm going to go ahead and return to div and I'm going to also have an H1 tag inside and I'll just say welcome user okay if I go to my browser you'll see that it says welcome user now let's say for example if I were to change the value of is authenticated from True to false you'll see that now the browser does not display welcome user now it should be obvious because is authenticated is now false so this block of code does not get executed so it never reaches this return statement and we're not returning anything after this check so that's the reason why it's currently just a blank page so what I could do is I could actually just add an else an else block over here and I could just return another div and I'll just say you are not logged in I could wrap this in an H1 tag as well I'll just do a span tag and now you'll see it says you are not logged in now you don't really need this else case you can just actually remove that and just straight just return this dat right over here because if is authenticated is false then this block is not going to be returned or this uh this line of code is not going to be executed and then we're just going to just jump to this part and just return this default message if the user is not logged in okay and that's literally it when it comes to conditional rendering you just have an if condition and then if you need let's say an else block you can have the else block if you need else if to check to see if the value is equal to something else you can add an Els if as well okay now I'm going to show you the more common way to actually write this so instead of using an actual F else statement we're going to use a Turner operator okay now turn operators may be something that you may not be familiar with especially if you're just new to programming but you should definitely learn what Turner operators are because you're going to be using them everywhere in literally every single react project okay if you work on an open source react project you're going to be seeing them everywhere whenever it comes to conditional rendering so the easiest way to explain what a tary operator is and how it looks like is just by showing you some documentation now this is what a tary operator looks like you can easily get this page by just Googling tary operator and it should be like the first or second result on Google okay so basically a Turner operator is also another conditional operator as well and it basically takes three operand okay so this is what it looks like right over here let me zoom in just a little bit so right over here we have our tary operator and we have three oper we have the condition and then we have the two values that will be returned based on the uh conditional value so the way that it looks like is you have your condition and then you have this question mark okay on the right hand side of the question mark this is where you want to place the values that you want to return based on the condition so for example is member is going to be a true or false value it's a conditional value so if is member is true what's going to happen is it's going to return this value over here $2 which is on the left hand side of this colon symbol if is member is false it will return $10 so whatever is on the right hand side I honestly think this is the easiest way to understand turn operators so just remember that you have this question mark on the left hand side of the question mark you have your condition and then on the right hand side of the question mark you have your two other oper where you're going to return a value right over here on the left hand side of the colon if is member is true and if is member is false or in other words if the condition is false then it's going to return whatever is on the right hand side of the colon okay so I just recommend you practice turn rate operators because you're going to be using them a lot but hopefully this makes sense so we're going to go into our component and we're just going to go ahead and write the same logic that we had previously but using a Turner operator so we're going to use the return keyword and remember we need our conditional statement so the first thing that I'm going to do is reference is authenticated because even though this itself is a variable that is a literal value true or false it still is a conditional statement as well so return is authenticated and then we need our question mark symbol and then on the right hand side of the question mark we want to set up our two operand okay so the first operan is going to be what is going to be returned if is authenticated is true so that's what this div with the H1 tag will be and I'll just say welcome user okay now I need my colon and on the right hand side of this colon we're going to go ahead and return the div with the text you are not logged in and this div will be returned if is authenticated is false okay so this is literally what it looks like as a tary operator or in the form of a turnning operator if I go back to my browser you'll see that right now it says you not logged in and that's because is authenticated is false so when we go to our tary operator over here is authenticated is false okay so it's going to go ahead and return what is on the right hand side of the colon so dis right over here with the H1 tag that says you are not logged in if I go ahead and if I change is authenticated's value to true now it's going to go ahead and return what is on the left hand side of this colon so it's going to return this div with the H1 that says welcome user and if I go to the browser you can see that this is what is being displayed to us so hopefully this makes sense now so far the examples that I was showing you uh dealt with values that only had two possible values either true or false and that's pretty simple but sometimes you might want to check the value of a specific variable or property on an object that may have more than two possible values okay so a good example example of this would be let's say you're building a system where you have a user and they have different statuses okay so the user status can be uh not verified which could mean they didn't verify their email or their phone number and then the other status can be verified which means that they verify their email or their phone number and then the other status could be account disabled which means that the user disabled their account so they no longer want to be able to uh you know actess access the account unless they reenable their account again so in this situation we have a status that has three possible values there could be more there could be four five or six or maybe even seven different statuses it's just up to you and your implementation so what I'll do is I'll declare a variable and I'll call this user status okay and then what I'll do is I'll just set the value currently to not verified now I'll just leave a comment up top over here just so we can uh remember what the values could possibly be of user status so do not verified verified and account disabled okay now in a situation like this we'll definitely need an if and else if statement as well because before we only did an if and then an else statement we didn't do else if so what what I'll do here is I'll check to see if the user status is is equal to not verified so if it's equal to not verified then I will return and you guessed it some jsx so this will be a div and we'll just simply use a span tag and I'll just say or not verified please verify your email or mobile number okay and then let's go ahead and check to see if the user status is verified okay so else if user status equals verified so if the user status is equal to verified then we can display to the user let's say their personalized dashboard we can display you know a confirmation screen saying that oh you now verified whatever it is whatever makes sense to your application of course okay I'll just display something simple I'll just say you are verified congrats click here to access your dashboard obviously we don't have a dashboard built out so I'm just going to write some text and then now we need to check for the third status the third possible value of our user status variable which is account disabled okay so in this situation I actually have two options okay since I've already handled not verified and verified I've already checked to see if the user status is verified or not verified so if we 100% know that these are the only possible three values then I can actually just use an else case right over here and this kind of just acts like a default case right which means which implies that the status is account disabled personally I don't like doing this because I like to be explicit with checking my value use but if you want to just use an else case that would work just fine because at this point we already know that the user status isn't not verified it isn't verified and that leaves us with only one other possibility which is accountor disabled now you might have a situation where if you're building your application and let's say you don't set a status on the user you might set it to null or undefined then you definitely will need to check uh with an lsif case you need to check the user status if it's equal to account disabled and then you can have an else case also known as the default case which handles when the user status is null okay so I'll actually show you um both scenarios so right over here in this else case I know that the value is going to be account disabled if we reach this block so I'll just go ahead and say your account is disabled okay now let's go back to our browser and let's take a look at all of the possible scenario so right now it says you not verified and that's because our user status is equal to not verified if I change the value of this variable to verified you're going to see now it says you are verified congrats if I go ahead if I change this let's if I just set this to null okay so since I'm setting user status a null that means this condition is going to fail user status equals to not verifi that's obviously false this Els if this is going to fail as well because user status is not equal to verified so this is also false and then what's going to happen is it's going to go to this else block and then it's going to return this div with this span that's all you see over here your account is disabled okay now again that doesn't necessarily mean that the account is disabled it could just mean that in the system you didn't actually explicitly set the status when you may have created the user so this is obviously not a good way to you know handle that situation so what I'll do is I'll write an L if and I'll say user status equals account disabled and then now I'll just go ahead and copy this and paste this over here and I'll just say your account is disabled okay and if the user doesn't have any status AK if the user status is null or undefined I'll just say please contact a system admin okay so now you'll see that it says please contact the system admin because user status is null if I change it to account disabled it will now say your account is disabled so notice how we're not using a tary operator in this situation we're using an if else or if else if else statement right and in this situation it's perfectly fine to use these explicit conditional statements because in a ter with with a turn operator you're going to need to actually Nest a bunch of operands and it's going to make your code look very ugly and I just think it isn't really ideal and especially if you use linters such as es lint or prettier sometimes they might have rules sets where they don't want you to Nest tary operators so avoid nesting Turner operators if you have to check multiple values more than two for a condition definitely use an explicit if else if else statements you can also use a switch case as well and I'll quickly show you how to use a switch case or switch statement so what I'll do is I'll use a switch and I'll go ahead and just comment all this out real quick let's use a switch switch case so user status will be our condition and then we need to set up our case so we'll do well the first one we'll do is not verified and then uh what I'll do is I'll just return and I'll literally just return this right over here I may need to you know let me uncommon all this out just so it's easier for me to copy and paste all this okay we're just basically converting all this into a switch now let me go ahead and copy this to handle a case where it is verified okay and let me remove this then let me go ahead and copy this right over here and then that's going to be the case for account disabled and then the default case for switch statement default just like this okay so this is what it looks like as a switch statement you have your switch keyword and then you have your condition which is user status because we're checking the value of user status and then we have four cases we have case not verified case verified case account disabled and then the default case which is the equivalent of our else block that we had earlier okay and then you'll notice that if I were to change the value of user status each time it's going to go ahead and pretty much return the corresponding div with its text so current Curr user status is equal to account disabled so it's going to say your account is disabled if I change this to verified it's going to return your verified you can go ahead and play around with the values and see how it Handling Events works but hopefully this all makes sense in this section of our react tutorial I'm going to teach you how to perform event handling on your HT ml elements event handling is a very important thing that you must learn how to do because majority of the time whenever you're building out your user interfaces it is very likely that you will need to handle events and there are are a lot of different events that you can handle for your HT elements but I'll cover the most common ones that you will come across such as handling events for user input in other words whenever you have a user needing to type data into a form and submitting that to a server you're going to need to register events for that so what I'll do is I'll create a new component and I'll call this login form so we'll set up a very basic form that a user can enter their username and password and then we'll also create a button that they can click on and we'll pretend like that button is sending data to a server obviously we don't have a server to send data 2 but the idea behind this is to show you how to actually register these event listeners on these HTML elements so I'm going to call my component login form. jsx or the file and then we're going to go ahead and Export a function called login form and then what I'll do is I'll just return a form okay and what I'll do here is is I'll set up two input Fields I'll set up one which is going to be for the username and we want to make sure we associate our input Fields with a label so I'm going to give this input field an ID called username and then for the label we want to have this HTML 4 attribute and then it's just going to be associated with whatever the ID of this input is which is user name so we want these to match and then for the label text we'll just use username and this should be it let's go ahead and render our login form in our app component so let's render that and let's make sure that it is appearing on the screen and it is and when I click on the label itself you'll see that it focuses on the input field which means that we've Associated this label with the input field correctly okay let's go back to our login form and let's do the same thing for the password field before I do that though let me go ahead and add a Break Tag after label so that way it is on the next line This input field so I'll copy this full thing and I'll paste this and then we'll just change this to password copy that change the ID of this second input field to password as well then change the text from username to pass password for the second label and then you can see when I click on it it is properly associated with the second input field let me also go ahead and add a Break Tag right over here and let's see let me also do one more thing I'll go ahead and set the type of the input to password so that way when I type in here you'll see that we have the password hidden okay so hopefully this is pretty straightforward again regular HTML regular HTML form so I can type my username and I can type my password let's go ahead and set up a button and we'll just go ahead and give it the text login and let's also make it on the next line as well there we go all right so now what we want to do is is whenever we are typing into our input fields we want to be able to detect whenever the user is typing in these input Fields but we also want to grab the data that they are typing okay now again there are a lot of different events that you can handle so if you just go to this input field this input element right over here and if you just type on you can scroll through all of these different events that you can handle and again some of these events are pretty self-explanatory a lot of these events would not make sense to handle on an input field but the most common one that we would want to handle Input Field onChange Event is the onchange events now this event is basically going to trigger whenever the value of the input field is changed hence the name on change now the value that we want to pass to this on change event because it expects a value it's going to be a function that it needs to call and this is typically known as an event handler so all it really is is just a function and I can just pass in a regular Anonymous function inside just as a regular value for this onchange attribute and I can just write a console log for now so every single time the value of the input field is changed it's going to go ahead and invoke this function it's going to call this event handler and you're probably wondering well what exactly do we mean by value of the input field well I'll show you so this callback function this event handler function actually takes in an argument and it's known as the event object okay to be more specific it's actually a change event type so I can actually console log this e typically you can name it e or events you can call it whatever you want but commonly people name it e or events okay and there are a bunch of properties on this event object and one of them is actually the Target and the target itself references the actual HTML element itself you'll see in just a second so what I'll do is I'll go into the browser right now and let me just refresh the page and and I'm going to go to the username field because that's the current element that we have our on change event being uh registered now whenever I change the value of the input field and the way you do that is literally just by typing so if I just type something you'll see that it logs the actual Target so the input field itself and then you'll see it says value change and every single time I type something it's going to say value changed and I can type literally anything I want it's going to keep on calling this function this event handler whenever the value changes okay so hopefully that makes sense just to be more specific this onchange event is not necessarily detecting whenever a user is typing it's just detecting whenever the value of the input field is being changed and in order to change that is by typing into the input field so you can think of it as it is is kind of like you know detecting whenever a user is typing but I do want to be more specific with what exactly is going on there are actual events that you can register that specifically are for detecting whenever a user press a key so for example there's an Onkey down event and this event is triggered whenever you actually press a key so for example I'll just log e Let me refresh and if I type something if I just press a key you'll see that right over here on line 13 which is where we have our console log so right now the on key down is being triggered and it's calling this function and keep in mind that you can have as many events registered on a single element so you can have literally every single event possible being registered on an element so right now you can see that the Onkey down event is being triggered and there's actually this property that you can see called key and this key actually tells you what the actual key was pressed so if I do e. key Let me refresh so if I type A you'll see that it logs uh whatever the value of e. key is which is a if I type B you're going to see says b c you're going to see it logs C and notice how if I hold shift it literally logs shift and then if I do shift a you'll see that it logs shift a okay now I'll go ahead and actually just remove the on key down event handler just so I'm not confusing you all okay so going back to our on change event the important field that we want to reference is actually the value of the input field so in order to actually get the value of the input field in other words whatever the user is typing we want to reference the value property on the event. target property itself so e. Target is an actual object and it has this value property itself okay and again if you've worked with client sided JavaScript and just plain HTML Cs and JavaScript this target element is literally an HTML element instance to be more specific in HTML input element instance okay so you can see that when I reference Target there are a bunch of different properties that you might be familiar with okay you can scroll through all of it so for example if you wanted to see all of the possible classes that are associated with this input field to give it certain Styles you could reference e. target class list and that would give you a list or an array of all of the classes that are on this input element okay but we want to reference value and now what I'll do is let me refresh so if I type my username let's just say ansen you'll see that each time I type it logs five times but you can see that we have ansen at the fifth time it was logged okay so this tells me that this is what my username is because we actually want to get what whatever the user last typed okay whatever the last value is so it's kind of like it incrementally builds up the username so it goes from a to a an to a ANS to an anso and then an ANS o n okay so hopefully that makes sense so again if I keep typing um let's just say Anon the developer the moment I stop this is going to be the last value that was typed into this username field and if I just went ahead and I just deleted the whole thing you'll see that the value of the username field is empty and I can actually just copy and paste stuff in here directly and you'll see that it just goes ahead and gives us ANS in the developer as the value itself without having this whole uh thing being logged okay so this is why I said earlier that onchange event is not necessarily detecting whenever a user is typing it's just detecting whenever the input field is being changed and again that can happen either by typing either by pasting a value or if you have let's say an image upload system and you can also just drag and drop stuff into uh the input field which is something which is something else that we'll talk about possibly in another tutorial but hopefully this makes sense okay so let's go ahead and add the onchange event listener to our password field and it's the same way that we do it for the username field so we'll go down to our password field so this input field right over here we'll add the onchange events add a callback function aka the event handler whoops and remember the event handler takes one argument the events object and I'll just console log and I'll use a template string so that way I can have a formatted uh display so password and then e. target. value and I'll do the same thing for username so that way we have a more formatted text so e. targets. value okay this is a template string right over here so now what I'll do is I'll refresh and I'll just type anen the dev and for my password we'll just type password and now you can see that right over here I type an the dev so it logged uh literally let's see a total of I believe 11 times so 1 2 3 4 5 6 7 8 9 10 11 so it called the onchange event handler 11 times for the username field okay we didn't do anything else for that input field after and then we went ahead and typed uh a total of eight characters in the password field so it called the on change event eight times okay now if I were to click the login button what would happen is we would want to submit whatever the latest values for our form Fields so for example the latest value for for the username field is anen to Dev and the latest value for the password field is just password so these are the values that we would want to send to the server because that's what the user last inputed now there are many ways that you can handle form submission on the front end side so right now we currently have just a very basic form with two input fields and then we have a button inside our form now one thing that I want to show you that you should definitely know is there is a default behavior that the browser will do okay so you can see right over here if I actually just click on this login button you'll see that it looks like the browser is refreshing okay you can see over here that this refresh icon is going from the refresh icon to the X icon so it looks like the page is refreshing so if I if I were to type something in the username field if I click login notice how when I click log in the page refreshes and then the field is all cleared out so this is the default behavior of the browser you can actually prevent this and I'll show you how to do that but the default behavior of a form what happens is this so there are actually two attributes there is this method attribute and typically you set this to either get or post it depends on what you're trying to do typically if you're logging in or if you're creating data on the server side in other words let's say if you're uh creating a blog post you would want this method to be post okay so that is specifying the HTTP method that you are using and then there is this action attribute which is going to be the path that you're sending the data to okay so this would literally just be something like SL API login and if I actually go to the network tab right now and let me just filter by fetch you'll see that whoops okay so ignore this ignore the network tab just look right over here when I clicked on uh the button you'll see that it says this Local Host page can't be found uh and you'll notice that the the route actually got updated to SL API loged in so it tried to actually uh make a request to this path on the same domain on Local Host Port 5173 API login we don't have that path so that's the reason why we're getting a 404 uh error and that's okay but I just wanted to show you what happens by default when you click on the login button now what I'm going to do is I'm going to show you how to prevent this default behavior from happening because actually nowadays you don't actually want to submit data this way using the method and action attribute because what happens is the whole page just refreshes and then you might lose uh some action from happening on the page we want to do things asynchronously in other words we want to just send the data to the server without having to refresh the page entirely because there might be something going on that we're waiting for to happen on the page that we don't want to necessarily cancel okay so I'm going to remove these two and what I'm Form onSubmit Event going to do is I'm going to handle an event called onsubmit okay and again this is just a regular event that takes in a callback function and then it's also going to take in this event object as well again every single event handle will have this event object that you can optionally pass as an argument if you need it but what I want to do is I want to reference this event object and then there's this method called prevent default okay and I want to show you what happens now if I were to click on the login button notice how now when I click on the login button the page does not refresh anymore if if I type into my form Fields And if I click log in you'll see that the page doesn't refresh and our form fields are not cleared out okay I mean they were being cleared out because the page was refreshing but you can see that it's not refreshing the page anymore okay let me fix the path real quick no more it's not being refreshed anymore but if I remove this prevent default you'll see that it is now refreshing so what did prevent default method does is it literally just prevents the default behavior of the browser so remember what I said earlier is the browser will have its own default behavior that it will do for events and there are a bunch of different default behaviors that the browser will resort to and you can always override this by literally just calling this method because sometimes you might not want to have the browser's default Behavior occurring you want to handle your own actions for your event and we'll explore them as we handle different events okay so what I want to do in this event is first I want to prevent the page from reloading and then what I want to do is I want to get the latest values that were uh typed into the input field so to achieve this what we're going to do first is let me actually go to my input fields and there was actually this was something that I should have done earlier I want to associate the input field with a name so you typically want to give a unique name for your input Fields so for example for username I'm just going to give it the name username and then for password I'm going to give it the name password okay so that way the actual form element knows the name of these input Fields okay now what I'm going to do is I need to actually get a reference to the form element itself and we can do that by referencing this event object for the uh event handler that we used for onsubmit so if I reference e. Target inside this onsubmit event handler function this would actually get me the HTML form element instance which is the actual form element itself now what we're going to use the form element for is we're actually going to pass it as a value to a form data class construct structor so form data is actually a class that you can use that will actually allow you to retrieve values from the form element itself so the way that we can do that is first we'll declare a variable called form data just like this and then we'll create an instance of the form data class so equals new and then form data and this is again built into the browser API and then we'll pass in the HTML form Elements which is going to be e. Target and now what I can do is I'll console log form data and let's just see what it looks like when we log this form data instance so if I click log in you'll see that current it looks like it's an empty object but I believe it's because it's not properly serialized but what I can do here is I can actually reference form data and I can reference get and then I can pass in the name of the input field that I want to retrieve the value for so for example if I wanted to get the data for our username input field well I'm just going to pass in username just like this okay and remember it needs to match this name value so for example remember how earlier I added the name attribute for my input fields and the value of name for the username and field is just username so that is what we need to pass in so if I refresh if I click log in you'll see right now it is logging the value of username if I type ansen you'll see that when I click the login button it is logging ansen which is the value that was retrieved from the form data doget function call and it's literally just getting that data from the form data object itself and notice how if I remove this name add attribute from the input field it's just going to return null so you need the name attribute in order for this to work now obviously um this is only one of many ways that you can use to handle a retrieving form data later on when we get to actually managing State and you'll learn how to bind your input fields to State variables so you won't actually need to do it this way okay but this is one way that you can use to actually get the form data itself okay so similarly if you wanted to get the the value for the password input field well you would literally just reference form data and then call the doget method so doing the same exact thing that we did for username we just do it for password so form data. getet and then we pass in password which is the value that we set for the name attribute for the the password input field okay so just again if if the name value was password 1 2 3 then the value that you would pass over here is password 1 23 just like that and now if I type something for password it'll see now it's going to log that value on line 8 or password okay so let's go ahead and do this let me assign this to a variable so form data. getet username and then we'll do the same thing for password let me just change this back to password instead of password 1 2 3 and then cons password equals form data. password and now what I'll do is I'll just pretend like I want to submit this to some server right so you might make some API call so for example there a built-in fetch API that is part of the browser and you can use this to submit data to a server so you can pass in some URL and again some of you may not know how to do this quite yet because you haven't worked with backing stuff don't worry we'll get to that later on but just as a preview you would pass in a URL to the server so let's just pretend it's Local Host Port 3001 and then you would pass in your data just like this and then username name then password something like this okay and then you for fetch you also need to set the method and typically we want to set it to post for logging in okay so this is what a potential API request could look like where you attach the username and password in the request body then you pass in the method type which is going to be post and yeah and then of course you would just wait for a response from the server and then you would handle that accordingly so if the user successfully logs in you may want to redirect them to their dashboard page so hopefully all of this stuff makes sense when it comes to registering events for your HTML elements now there Registering Window Events are other events that you may want to register not on a specific element but sometimes on the entire page itself that the user on so a good example of this is let's say you want to detect whenever the user is scrolling or if the browser size the window size has changed so in that situation you may want to actually use the global window object and then use this add event listener method which some of you may be familiar with this if you have learned how to register events dynamically using plain JavaScript for your HTM elements so window. addevent listener and then there is this resize event and then we'll pass in The Listener function just like this and then I can just literally log e doin there should be uh screen I believe screen X I believe is the property let me zoom out a little bit and let me open up the browser tools so if I resize this you'll see that every single time I change the size of the viewport it goes ahead and logs uh this object over here this window object uh let's see actually I believe it's not e we want to log window. screen X and then window. screen y okay and then now let's refresh and if I resize you'll see that every single time I'm sorry this is actually the position inner height and inner width is what I want so sorry about that okay so notice how every single time I resize the page the height is obviously the same but the width is getting smaller and smaller okay you can see the current page size is 682 by 1359 and that is being logged over here of course if I uh were to change the height you'll see that that is going to be logged over here 699 by 509 or the other way around okay so that is how you can detect whenever the size of the page is being changed so you might want to do this if you want to handle certain Dynamic um viewports using JavaScript but a lot of times whenever you're handling responsive design you want to do that with CSS but there might be situations where you need to do that with JavaScript and that's how you could do it using the resize events okay now typically you don't want to do it like this you'd want to actually wrap this in a use effect hook I'm not going to show you that right now because we haven't gone to hooks yet but later on when you actually learn about hooks I'll show you another example on how to properly handle those events with hooks okay so just wanted to show you a quick example hopefully this all makes sense and I'll see you in the next State section in this section of our react tutorial I'm going to teach you about States state is literally just a representation of data that can change over time we use state to represent data that is stored in a component you can think of State like a variable it holds your data but instead state is actually just an internal object for the component that is managed by react and react actually gives you the necessary tools to create new state values and manage them stay is necessary because it enables our components to store data that can be used later or updated imagine you're creating a card game let's say Blackjack and you want to keep track of the number of cards dealt in every player's hand you know that such information will change as the number of cards dealt will increase as the game progresses and the player's hand will change after each turn so you would need to track all of this information and to do this we would need State now you don't always need State all the components that we've created so far have no State I'll show you some examples now of how we can create some stateful components now what I'll do is I'll actually create a form in the previous example I actually created a login form with two input Fields but I actually didn't use any state at all we were able to track the username and password using the form data API but instead what I'm going to do is I'm going to Define some State and I'm going to show you how to bind the state values or the state variables to our input fields and this is actually known as data binding and it's a a very important topic to understand and it's usually what you would want to do to create forms instead of just grabbing it from the form data API so what I'll do is I'll create a new file inside my components folder and I'll call this register form so this will just be a form where we will have the user enter in their new account details so if they want to create an account they'll create it through this form so let's do this export function register form and we're going to return a form and I'm just going to Simply create a couple of input Fields uh and what I'll do is this I'll wrap every single input field in a div I'll also make sure I associate it with a label so let me give this ID I'll do uh this let's do username and we want to make sure we associate this label with the correct input field so I'm going to pass the ID that I assigned to this input field as the value for HTML 4 for this label oops okay and then I'm just going to copy and paste this twice and then we'll do password password and then I'll just do uh display name I'm not going to do a confirm password you can you can do whatever you want to and then I'll just do display name just like this let me go ahead and make sure I render this register form I'm going to remove the login form render in the app component and I want to render the register form instead just so we we don't confuse everything I'm going to remove the import and let's go to our application now so I have my form displayed in the document that's great now let's go ahead and Define some state for each one of our form field so basically what I want to do is I want to create some State variables or some State values that will represent my username my password and my display name so whenever I am typing in the username form field I want want to update the state value for the username for the password as well as the display name this will give me full control of each value and I can do whatever I want with it I can send it to an API I can display it to the user in real time as they are typing whatever it is now in order for us to create some State we need to use a function and that function is called use State and we can import this function from the react package so we're just useState Hook going to import use State like this from react okay so import you state inside the pair of curly braces because it's a named import and then from react just like this now one thing that I also want to mention is that Ed state is also a react hook react hooks are something that we have not yet talked about but don't worry and in a separate section of this react tutorial we will formally introduce to you all react hooks remember that react hooks are also just functions okay so react Hooks and functions are synonymous so this use state is a function it's also a react hook and we want to invoke this function because just importing itself is not going to do anything we need to invoke this function in order to do something so whenever you want to create state you use the used State hook or the Ed State function you call it and this used State function will always return an array with two elements okay I'm going to go ahead and conso log UST state right now before I do anything else and I want to show you in the document what this looks like so right now you can see that when I log U States or the the invocation of UST state so I'm calling UST State and I'm logging the value that's returned you can see that it's an array and there are only two elements the first element is undefined and the second element is a function okay so what the first element is is actually going to be the value of your default state so so far we actually didn't pass in anything into this use State function call so you can actually pass in an initial State and for example if I wanted to pass in an empty string I could if I wanted to pass in hello world I could and then you'll see that when you log it the array now has the first element is a string hello world and the second element is a function okay so you can also pass in a numeric value so you can pass in one and then you'll see that it logs one you can pass in a a Bine and it will log true you can pass in an object and then it'll log that object right over here okay so I just want to show you how this works you can pass in literally anything you want in our example we obviously want to make sure we're passing an empty string or just a string in general because we're working with text in our form Fields so it makes sense for us to have a empty string as a default value otherwise it will just be undefined by default okay now the other thing that I want to mention is this function so before I mention that function let me go ahead and show you the proper syntax of how to actually create States so you do call this UST State function and remember that it returns an array now you can actually reference that array in many different ways so for example I can just I can just assign the return value of U state to a regular variable just like this okay and if I wanted to I can just reference each element by referencing the index so result at subscript zero and result at subscript one okay now obviously this is not the correct approach I mean you can do this it's not wrong but I'm going to show you the right way to do this okay because I know some people might think about oh can I just access like this yes you can but you shouldn't okay so remember that the first value in the array that is returned from you state will always be your state value okay by default it will be whatever you pass in to UST State as an argument and then the second element is going to be your function this function is a very special function it's called A dispatch function some people call it a Setter function or an updater function all correct terms but it's resp responsibility is to update your state variable okay remember how earlier I said react gives you the necessary tools to manage your state and that entails creating your state updating your state etc etc well this is how we can manage our state so what I want to do is I want to use array destructuring and the way that it looks like is this I'm going to go ahead and have my const keyword and then after con I'm going to have my square bracket and then inside the square bracket I'm basically unpacking the elements from the array and then I'm giving it a name at the same time so it looks like this I'm going to call the first element username and then the second element is my function and I'm going to call it set username just like this okay if you haven't worked with array destructuring before this might look a little bit weird but all you need to know is that remember you state returns an array and all I'm doing is I am just taking the values from each index each position of that array and I am giving it a name so for example the first value is going to be username and I'm calling that value username the second value is my function my updator function and I'm giving it a name called set username okay you typically want to call your function your updator function uh um set and then the name of your state variable okay so username and then the function is going to be called set username okay we're going to do the same thing for password and display name so go ahead and do the same thing for the next two so we're going to do const password and then my Setter function or my updator function is going to be called set password and then I'm going to call the use State variable or I'm sorry UST State function I'm going to pass it a default value of an empty string I'll do the same thing for display name and I'll call the state variable display name and then the setter function will be called set display name just like this so right now I have created a total of three state variables and each state variable has its own updator function okay for the rest of this video I'm going to call this function a dispatcher function okay cuz that's the formal term because if you hover over this it actually uh says that the type is a dispatch function okay so now what I'm going to do is I'm going to go ahead and take each state Binding State to Input Fields variable and I'm going to bind it to my input fields and the way that we can do that is like this so remember that the input field actually has an attribute called value so what I can do is I can say okay well I want to associate the value of the input field with the value of my state so for username I'm going to associate username uh or I'm going to associate the username input field uh with the username States just like this I'm going to do the same thing for the password so value equals password just like that and then display name we're going to do the same thing now right now if I go to my form if I try to type right now I'm typing right now and you'll notice that nothing is actually appearing in the text box I can't see what I'm typing okay and you'll also notice that we have a warning and it's saying that you provided a value to a form field without an onchange Handler so the reason why we cannot see what we're typing is because we also need to make sure that since we are binding our state variables to uh an input field we need to make sure that as we are typing we are using an onchange event handler to update the state otherwise it's never going to update at all okay so I'm going to go through each input field and I'm going to use the onchange hander and remember that in the previous section we did learn how to use event handling and we did use the onchange Handler remember that whenever you type or whenever you copy and paste something into that input field basically whenever the value of the input field changes this event is triggered so what I can do is I can pass a callback function and that callback function takes in one argument which has the event object okay and remember that event object has the target object which has the value and this value is basically going to have what you type or paste into the input field so what I want to do is I want to actually update the state value of username whenever the value of the input field changes so remember what what I said in order to update your state value you need to use your dispatcher function in our case we have our set username function so we're going to call that okay and then we're going to set the new username value with whatever the e. target. value is okay so in other words whatever it is that I am typing or pasting into the input field is going to be passed as an argument to the set username dispatch function and this will basically uh perform an update to the username State variable okay so now you'll notice that if I actually begin typing you'll see that now I can actually type into the username box okay but obviously you don't really visually see anything that's going on so here's what I'll do I'm going to go ahead and render this username State variable to the document just so you can see it changing in real time as I am typing so what I'll do is right down below I'll just go ahead and create a div and I'll just say this uh username and then I'll evaluate the username like this so now watch this as I am typing you'll see that that each time I am updating the states of my username variable it actually is reflective on the document itself and that's because I am updating the state by calling the set username function okay now of course if I removed this on change event handler and if I refresh you'll notice that as I'm typing nothing is happening nothing is being displayed to the document because we're not updating the username State at all okay hopefully this makes sense let's go ahead and do the same thing for the password field and the display name field so again this is how you're always going to want to create your forms in react okay we're going to have our onchange Handler and basically we're going to pass in that callback function that callback function will have one argument the event object and then since we are um binding the password uh State variable to the input field right over here we want to make sure that we are calling set password whenever we are changing the value of this password input field so I'll call set password and then pass an e. target. Val and then I'll do the same thing for display name so on change and I can actually do this shorthand I don't need the curly braces like this for this function I can just do set whoops let me fix this I I can do set display name e. Target value just like that okay just like that so let me remove the curly brace real quick I do this up a little bit there you go so now what I'll do down over here is let me just go ahead and copy and paste this a few more times and show you the values being changed in real time okay so let's evaluate each state variable so if I go back to the document you'll see now the warnings all disappear because we have appropriately uh registered an onchange event handler to each form field since we binded the value to each input field so if I type something for username type something for password type something for display name you can see that it is being updated every single time I change the value of the username password and this play name field and it is being rendered to the document okay now you're probably wondering well how does this form example differ from our login form example right because in our login form example we had no State at all but we were still able to access the username and the password via the form data API now the major difference here is that in our login form we don't have any state and we're getting the information from the the form data API and you'll notice that the only way that we're able to grab this data is whenever we actually trigger the onsubmit function or I'm sorry whenever the onsubmit event is being triggered and then it calls this callback function over here and then we create an instance of form data and we pass in the Target which is going to be the form element itself and that's how we can grab the user and password now here's the thing though right I could actually move move uh this form data instance up a layer so I can actually move this up top over here okay but if I move this up top over here so before the return I don't have access to the actual form element itself okay so I can't just grab the information like that so the only way for me to get the username and the password is by clicking on the submit button and sometimes we don't want to do that because clicking on the submit button means that you are going to submit the data to the API but perhaps you're not ready to send that data to the server just yet you want to perform some kind of validation in real time to give the user feedback so they can make changes to what it is that they entered in the input field okay in this login form example there's no way for us to access the data via State the only way that we can do it is from the actual form uh element itself okay and this is not necessarily good in this register form example I can literally grab the username field whenever I want okay so for example you can see that like I said we binded the username variable to this input field and then every single time the value changes we are calling the set username function which updates the value of username so whenever this field is updated I can always rely on react to update the value of the username field and and I can get the latest updated value of username okay in the login form example we can't get the username without clicking on the submit button so this allows me to do a lot of different things like for example um I'll I'll show you an example right let's go ahead and create a button uh and let's call this sign up okay let's say for example I only want this sign up button to be enabled if all three form fields are filled out okay how do we do that well remember now that we have state what I can do is I can write some logic I can write a conditional to check to see if username password and display name Are all uh filled out in other words um they all have a link greater than one or they're just all non-empty string so what I'll do is I'll create a variable and I'll call this is disabled so this variable is going to represent whether the button sign up will be disabled or not okay so remember that if at least one of these form fields are not filled out then we want the button to be disabled that means the user must fill every single form field in order for the sign up button to be enabled so what I can do is I can just basically uh do this remember that an empty string is a falsy value so I can just use a negation operator so if not username or not password or not display name so basically if username is a falsy value so if it's an empty string and then we negate that which evaluates to true that will basically mean is disabled will be true this whole statement will evaluate to true because remember with the conditional or if at least one of these conditions are true the entire conditional statement is true okay so if at least one of these evaluates true then is disabled will be true and then what I'll do now is I will go to the button and I'll use the disabled attributes and then I'll set it to the value of is disabled okay so now what I'll do is I'll go back to the document and you'll see now the sign up button is disabled but notice how if I type one thing into username if I type one thing into password but if I leave display name alone sign up is still disabled but the moment I type something to display name you can see that in real time the sign up button is now enabled if I delete a uh something from the password field like if I clear the entire password field okay so what happens is I remove the letter A from the password field making that password field empty right and since I updated the value of the password field set password was called okay the password State variable is now empty again which Updates this conditional statement over here okay since password is empty so remember password is a falsy value now not falsy which evaluates a true makes this is disabled variable true which means that the button will be disabled okay if I type something in password again sign up is now enabled so me having State enables me to create Dynamic buttons like this where I can enable it and disable it based on certain conditions that occur whenever I am updating either something in the input field or perhaps something changes in our component so hopefully this example makes sense so now in this example I'm going to show you how we can create one single object that has our username password and display name all set as fields and instead of just having three different individual State variables that we need to update will update the object and the specific field that we need to update so what I'll do do is I'm going to delete everything over here and I'll create a state variable I'm going to call it form fields and then the dispatch function will be called set form Fields we'll call use State this time we're going to pass an object okay we're going to set the object to have our username field which will be an empty string so this is going to be equivalent to having those three state variables just in the form of one single object so we'll have password initial value will be an empty string and then display name same thing we'll go ahead and update all the references to username instead of username it's going to be form fields. username because remember form Fields is now an object and we can access the username property on form Fields same thing with the password so form fields. password and then form fields. display name we'll do the same thing down over here where we rendering the data and I'm going to temporarily just comment out the button it's not really important right now okay so now we have our initial values set for our username password and display name inside this single object if I were to console log form fields and let me go ahead and just do this let me remove all of the original dispatch function that we were calling just so we can actually go to our browser tools so let me refresh the page you can see right now when I render the states when I render form fields we have an object that has all three of our values all set to an empty string and that's perfectly fine now when it comes to updating the state this time it's done a little bit differently because we're no longer updating a string we're updating an object so there is a couple things to keep in mind when you are updating something like an object when you're updating an object you need to pay attention to what exactly it is that you want to update so for example for my input field for username I want to make sure that I am updating the username and the username only I don't want to update the password or the display name whenever I'm typing stuff into the username box it wouldn't make sense so we need to be careful when we update the state so this time in our onchange event handler we're going to call set form fields and remember at form Fields is going to update form fields which is an object so in order for us to update our object successfully without touching any of the other properties the way that we want to do it is like this instead of passing an object which you might guess we might pass an object and then set the username to e. target. value okay you might guess that this is the right approach but it is not because right now by doing it this way yes you are updating the username but what you're doing is you are overriding the entire form Fields object okay so the way this would look like is you'll have the username updated but password and display name will be empty okay if you don't believe me I'll show you right now if I refresh the page I'm going to type something into username notice how now notice how now username this is uh the username is the only field that EX exists in the form Fields object password and display name no longer exist as properties because the object that we passed to set form Fields is the entire literal object that we are updating form Fields with okay and you can even see that we get a warning it says a component is changing a controlled input to be uncontrolled okay and we no longer have form Fields password defined or form Fields display name defined that's why this warning is popping up so the correct approach to updating an object that you have as a state variable is like this inside our dispatch function we can actually pass in a callback function and this callback function takes in an argument and this argument is actually a copy of the current state itself which actually I shouldn't call it previous I'm going to call it current states okay so this current state is literally just whatever form Fields is so you can see I can reference the username password and display name just like just like a regular object because that's literally what form Fields is now what I want to do and this is how you update State and react and this will look very similar to any other framework or library that you may use is you want to basically create a copy of the current states so you want to take all of the values in the form Fields object and the way we're going to create a copy of the current state value is we're going to use the spreader operator on the current state object so I'm going to go ahead and return a new object inside this call function over here so I'm going to use a pair of parentheses that will wrap this pair of curly brace and this is a short hand notation for us to return an object and then all I'm going to do is just use the spread operator on the current state current state object some of you might be wondering well couldn't I actually just do it on the form Fields object itself you don't want to do this because form Fields itself is the actual State and you never want to actually modify the state itself okay react has this immutable pattern where you want to never actually directly mutate data you want to do things in an immutable way and the other problem with with actually using form Fields is that you might not actually have the updated state for form Fields because the thing with updating state is that it is not guaranteed to be synchronous okay so you always want to make sure that you use this callback function and reference current States because this will give you the actual value of the current state itself so we're going to use the spreader operator on the current state object and what this will do is this will take all of the current key value pairs in the current state object and then unpack it into this new object over here that is wrapped in between these curly braces so basically if there is a current password if there is a current display name if there's a current username it's going to go ahead and put place it all inside this new object and then what we're going to do is we're going to just override the username field which is the field that we're updating after we spread the current state object itself okay so then over here what we're going to do is we're going to reference e. target. valal just like this so what this essentially does is it creates a copy of the current state object and then you have a copy of all of the key value pairs of current state and then you override the username field with whatever the e. target. Val is okay so this will basically preserve the password field and the value as well as the display name field and value but since we are adding this extra line over here setting the username field explicitly it's going to override the username field so in a nutshell you're basically creating a copy of the current state but only updating the username field so that way you preserve the password and the display name hopefully this makes sense okay so what I'm going to do is I'm going to copy this and I'm going to paste it for the onchange for password but instead and you may have guessed this instead of username instead of a manually setting the username we're going to manually set the password because remember when we update the password when we type stuff into the password field we want to preserve the username the display name but for the password we want to update the password with whatever the user whatever the user currently typed and the same goes for the display name field as well okay we want to preserve the username we want to preserve the password but for display name we want to make sure we update that display name with whatever we type into the display name field okay so now watch what happens I'm going to refresh the page and if I type for the username you can see right over here that it is updating the form Fields object every single time it's specifically targeting the username field okay and then I'm going to type something in password I'm going to type hello notice how it is updating the password field and it is preserving the username and the value of username which is Anson so let me go ahead and remove this uh spreader operator on the current state I'm just going to remove this entirely and now I want to show you what happens when I update the username so that works just fine but when I update the password you'll see that password is just being updated just fine but because we are not using the spreader operator on the current state to create a copy of the entire State itself we're not preserving the username or the display name and the object itself is only containing the password field so we do end up getting the same warning that we got earlier okay so it is very important to make sure that you use the spreader operator on the current state itself to create a copy of it and then specifically Target the field that you want to update so hopefully this makes State with Arrays sense in this section of our react tutorial we're going to continue with state but I'm going to show you how we can actually Define state for an array because a lot of times you're going to want to render lists of elements such as an array of users and then you may need to make updates to a specific element in that array and have it reflect on the application itself on the user's view so this is a very important concept so you definitely want to make sure you pay attention to this so what we're going to do is we're going to create some state so I'm going to have an array of users so I'm going to call my state variable users and then the dispatch function will be called set users and then I'm going to go ahead and call the UST State hook and I'll pass in an array and I'm going to just keep this simple so I will pass in two objects both will be representing users and one thing that I do want to also mention as well is that I have this user details component I created this very early on into our tutorial if you haven't been following along then you can either just create your own custom user details component or you can just copy this one uh this one is very simple there isn't any complex logic at all is just rendering plain text okay it takes in one single prop so we're just going to reuse this component just to save some time okay so we're going to make sure that each one of our users have an ID a username and an email address just to stay consistent with our user details prop so let's make sure we have an ID a username and then an email address address and then I'll go ahead and copy this object and paste it so I have two now and I'll just make sure I change the ID let me change the username as well as the email address now let's go ahead and render our users to the document and we should know how to do this this is known as Dynamic rendering or rendering lists which we've covered in previous sections of our react tutorial so we're going to use a pair of curly braces because we're going to be evaluating some JavaScript we're going to reference our user array and we're going to call the map function this function takes in a callback function also known as a transformation function and it takes in up to three arguments but we only need the first one and the first argument is just going to be the actual element itself that is inside the array that we are currently processing in other words we are currently transforming this user object into jsx something that is renderable so we're going to go ahead and have our callback function return jsx which is just going to be our user details component we need to make sure we import user details so let's go up over here and import that from the components folder user details file just like that now let's go ahead and make sure we pass in our props so the first one that we must pass in is the key remember that every single time you are rendering lists of objects or elements you always need a key associated with it so in this case I'm going to use the user ID as the key and then now what I'm going to do is I'm going to pass in the user prop just like that and for the user props value it's just literally going to be the object user itself okay and there shouldn't be any issues because we have the same key value payers ID username and email address so now if I go into the document you can see now I have both of my users being rendered to our page now this is wonderful but what if I want it to make updates to my users State variable so let's say down the road you want to add the option for your administrator to create a new user on the spot so you may have have a form that allows uh the admin to add a new user and then it will be updated on this view so you'll now see three users instead of two or perhaps you want to update uh a specific users's username such as anen or maybe you want to update their email address such as anen gmail.com and then you also want to make sure that those changes are saved and reflected onto the document or maybe you may want to also just delete the user entirely so these are all things that I'm going to cover so what I'm going to do is I'm going to go into my user details component and I'm going to go ahead and modify this component just a little bit just so that way we can suit our example so what we want to do is we want to give the user in this case ourselves the ability to edit each individual user to whatever it is that they want edited to okay in order for us to do this we obviously need some kind of text box for us to type stuff so we need an input field so this is going to combine all the things that we've learned so far such as conditional rendering handling forms handling events things like that okay and again if you haven't been following along with all of the previous sections up until now don't worry I'll do my best to explain every single thing that's going on as well so what what I'll do is the first thing that I want to do is I want to create some states I basically want to represent whether or not we are currently editing our user or not so we're going to go ahead and create a variable a state variable we're going to call this is editing so that's going to be the name of the variable and then the dispatch function will be called set is editing and then use state so the value of this will be a Bo or the type of this variable will be a boine and the default value will be false because by default we're not going to be in edit mode okay we're going to just be in regular View mode so now what I'm going to do is this for each user I also want to make sure I display an edit button that will allow me to change the state of the is editing variable so this will allow me to actually uh click on the button and then dis playay all of the input fields in order for us to make updates to our users so the way that I'm going to do this is let's see I think what I'll do is I think on the top of every user I'll just have an edit button so I'm going to go and just copy this div and create another div that I will just paste this whole thing inside and then up top over here or actually maybe on the bottom I I will do another div and I'll add a couple of buttons so the first one I'll do is edit so it'll look like this okay um if you want to get fancy you can also style this as well you can use like a flex box but again I'm not going to make this overly complicated you know let me actually move this up to the top just so that way this one pertains to this one okay I will also add another Button as well I'll add the delete button because later on I will show you how we can delete the user as well okay so the first thing that we want to do is whenever we click on this edit button we want to be able to toggle the state of is editing okay because when we click on the edit button we want to change our view from just regular view to actual edit mode so we need to register and onclick event listener onto this edit button and we just want to make sure we pass in our callback function like that this is known as an event an event handler and all we're really doing here is just calling set is editing and then passing in uh true but here's the thing though if I only click on this button this will always set is editing to true I want to actually toggle this so I don't actually want to set it to true I want to set it to um the opposite value of whatever the current state of is editing is so in other words if if is editing is currently false we want to set it to true if is editing is currently true we want to set it to false the best way to do this is by passing in this callback function and then remember this callback function actually takes in an argument which gives you the current state so this is the current state of is editing and then we can actually just do use a negation operator current state okay I actually uh showed you this example when we covered uh the register form example where we instead of actually passing in a literal value you can pass in a callback function because that callback function gives you access to the current state and you can actually return the new value for the state itself okay so what this will allow us to do is ensure that we are receiving the actual value of is editing and then just negating it so that way it is being toggled on and off okay so now what I want to do is this just very quickly I'll console log is editing just so you can see that it is in fact toggling so you can see now it goes from true false true false true false just like that perfect okay so what we want to do now is I want to conditionally render a form field whenever we are in editing mode so we know how to do conditional rendering so that shouldn't be any surprise so the only two things that I want to be able to edit or give the user the opportunity to edit is their username and their email address we don't want to allow them to edit their ID so what I'll do is for the username field right over here I'm going to go ahead and edit this right over here so I'm going to use a tary operator so is editing so if we are in edit mode then we will display an input field otherwise we will display just their username now I will make some changes to this input field in just a second I just want to show you how this will look like so if I refresh the page you can see right now we're currently in View mode okay if I click on the edit button it's going to take us to edit mode okay so that should be pretty straightforward we were're previously in View mode now we're in edit mode okay so let's go ahead and do the same thing for email address because we also want to just allow the user to edit their email address as well so let's do that is editing input or email okay if I click edit now you can see that we have our username field and our email field if I click this edit button down over here it will reflect on this user itself okay so hopefully this makes sense now let's go ahead and go back to our input fields we want to make sure that we have the correct attributes set so first for the username field let me set the name to username and then let me give this an ID of username as well uh and then let me go ahead and also set the value so we actually want to bind a state variable to to this input field so that way we can actually track the state of whatever the user is typing into this input field so we do need to create a state variable for the username so I'm going to do that right up top over here so cons username and then the dispatch function will be called set username and then we call use State Now the default value you might be wondering well I'm going to pass in an empty string right well you could but actually something better that might be more appropriate is we can actually pass in the users username and set that to be the default value and the reason why this would make sense is because first of all it would give a better experience for the user because think of it like this right when you've used the form before let me zoom out a little bit when you've used the form before and let's say you have tried to edit your own username when you click on the edit button you'll see this input field but then you'll also see your current username as well and not every single application does it this way but I personally think that it's better from a user experience standpoint so we're going to go ahead and do that so let's go ahead and pass the username as a value for this value attributes and then we need to make sure that we are adding an event handler for our input field whenever we are changing the value of the input field so that's going to be the onchange event handler and again I also covered this in the previous section when we talked about the register form so go ahead and check that part out if you haven't already so just remember that whenever we change the value of an input field in other words if I were to type something or paste something inside the input field it is going to trigger this onchange event so it's kind of like it is detecting whenever you are typing something but it doesn't necessarily mean that it is detecting keyboard Strokes just want it to be uh specific so we're going to pass in our event handle function remember that this function takes in the argument the event object itself and then what I'm going to do is every single time this function is called we want to update the state of username and to do that we just call set username and then we can pass in e. target. value okay now since the default value is just going to be username which is this state variable right over here and the default value of our username State variable is going to be whatever it was that was passed in uh as this user prop that means that whenever you are calling set username it'll basically just be whatever the user is either deleting or adding onto their current username unless if they just control xit in other words they just cut the entire input box and just paste it in something new okay so if I refresh you can see now if I click edit you'll see I have my username and then you can see that my current username is just right over here and I can type and I can change whatever I want okay so hopefully that makes sense we'll do the same thing for email so we'll go ahead and I'll just duplicate this line we'll change this from user. username to user. email and I'll change up the name of this from email uh to set email or I'm sorry from username to email and then from set username to set email and then now let's go down over here to our input field for the email and and we we'll just do the same exact thing I'm going to copy all these attributes and just paste them over here and we're going to set the name to email set the ID to email and one thing that you could also do with uh email Fields is you can actually set the type to email so that way this ensures that the user is actually entering an email okay but I'm just going to leave this alone for now I'm not going to do that we're going to bind the email State variable to this input field and then instead of just calling set username we're going to call set email okay so now if I click on edit you'll see that I have both my username and email Fields being displayed and it has the current status of our username and email inside the input boxes itself okay so now what we want to do is I want to be able to make changes to my username by typing into these fields and then I also want to make sure that I can click on a button to save these changes and then when I click on that button what needss to happen is we need to update that specific user object okay so there's a lot of other things that we have to do so we're going to take it step by step the first thing that we want to do is obviously have our save button so I think what I'll do is I think up top over here I'll just add a save button again this is not the most uh Pleasant viewing experience but again the whole purpose of this is to show you functionality over styling and looks okay you can worry about styling this up yourself later on but I just want to really just focus on functionality so we're going to add this save button right over here and then when we click on the save button we want to be able to update the state of our users okay so first off how do we actually do that okay how do we actually update this specific user as well as updating the user's State itself well well we need to actually first know which user we want to update and remember how earlier I told you that I will show you how we can grab that well it's actually a lot easier than you might expect so what I'll do right now is show you what happens whenever I click on this save button so onclick let me register this onclick event and then we'll just go ahead and console log the user itself and if I go into the document you'll see that if I click on this save button which pertains to this user over here I log the first user you can see the ID username and email are all over there if I click on this save button it logs the second user okay so this should tell you right off the bat that each one of these user details components are its own instances okay so although we might have you know the same type of user component being rendered they have their own State they have their own identity so they're not the same thing at all okay so knowing this I can very easily use the ID of the user to determine okay which specific user object do I want to edit because the way that we're going to update the state is like this we're going to go through the array and we're going to find the user that we want to update and then we're going to update the entire array as a whole now there's actually ways to do this in react without actually modifying the original array because remember that react you want to practice immutability you want to make sure that you are not actually directly modifying directly mutating the users's array itself you want to do things in an immutable way so while you might know how to necessarily directly mutate an original arrays contents you definitely don't want to do that in react okay so here's what I'm going to do we need to set up our components in a way where I can actually update the user State because right now we are kind of in a little bit of a situation you'll notice that the user's state is actually in a completely different component now remember that the app component is a parent component of our user details component making this a parent to child child to parent relationship okay but here's a nice thing though even though our state is Define at the parent level we can easily still modify this user state either by passing in this dispatch function down to the user details component itself or we can actually pass in a wrapper function to take care of managing the state for us I'll show you both ways the first way that I'll show you is just directly passing in the set users function so what I'll do is this so since we're going to pass in set users to the user details as a prop and remember that you can actually pass function as a prop to a component so what I'm going to do is since we are using prop validation I'm going to go ahead and make sure I add this to the prop types so set users will be a function is required okay I don't know why shape was not required I should have made this required there we go all right so now let's go ahead and get set users and let's pass this into set users I'm sorry let's pass in set users to user details okay so now we can easily call this function and I'm going to show you the proper way that we're going to invoke this function as well as updating the state so remember that whenever we click on the save button this is where we actually want to make the changes to the state itself okay so what we're going to do is inside the onclick event handler function this is where we want to make sure we are capturing the username the current state of the username so whatever the user updated it to and same thing for the email address okay so we need the Updating Element in State Array username and then we need the use we need the email address but then we also need to make sure we have the ID of the user which we can easily grab from user. ID now how do we actually modify the elements inside this users array how do we do that now there are a lot of ways that you can go about this but I'm going to show you the right approach that the react team actually recommends you to do so it also allows you to modify your state without actually directly mutating the array itself and I'm also going to mention one more thing I'm going to use an actual LL statement instead of using a turn operator because I don't want you all to get confused with the amount of parentheses that we're going to have I will show you both but I'm first going to show you how to do it with an if else condition so the first thing that we want to do is call our set users function that we passed in to our user details component remember that this function itself is our dispatched function and remember that we can actually pass in a callback function and the reason why we're going to pass in a callback function in this case is because I want access to the current state of users okay so I'm going to go ahead and call this variable current users stat okay and then I'm going to use a curly brace right over here because I'm going to have my code execute inside this block over here so what I'm going to do is I'm going to go ahead and return current users dot Uh current user state. map so I'm going to go ahead and call the map map function on this current user State remember this is an array of the current state of our users and the reason why I am calling map is because what we want to do essentially is we want to replace an element in the array and that's actually what this is all about we're replacing a specific element in our array and I think the easiest way and this is kind of the reason why I think the react team recommended you doing this on their docs is because this is the easiest way to do this without directly mutating State itself okay essentially what we're going to be doing is we're going to go through each element and we're going to actually write a condition so we're going to check to see if the correct user is being edited and if the user is in fact being edited then only we're going to replace the user with the updated one I'll show you what I mean right now so what we're going to do is we're going to pass in our callback function to the function remember this callback function takes up to three arguments but the argument that we care about is the element that's in the array itself which is going to be our user I'm going to call it current user because we have user already being defined up over here and we will need to reference this as well to do the comparison so that's why I'm not using user down over here okay so now what I'm going to do is this I'm going to write an if condition so if current user. ID is equal to user. ID and now you see why that I am renaming this variable to current user instead of using the same one up top over here so basically what this is checking for is ensuring that we are editing the correct user because we obviously don't want to manage every single user we don't want to edit every single user we only want to edit the user that is actually being edited okay so if this is true then all I'm going to do is return a new object and it's going to look like this I'm going to take every single key value pair from current user and create a copy of it inside this new object and then what I'm going to do is I'm going to explicitly set the username and email address because we know that those are two possible fields that could be updated now if the user didn't edit any of these fields like if they just didn't touch the fields at all then that would be fine because by default remember that the username of the user as well as the email of the user are set to these State variables by default okay so if they didn't update the email address for example then the email would stay the same so what I'm going to do is I'm going to set the username to the state variable username right up top over here and then same thing with the email as well so I'm setting this email field to whatever the value of the email State variable is now since these are the same name names I can actually just remove the colon and I can just do it like this okay and actually I don't need the parentheses because I'm using an explicit return keyword so you'll notice that my formatter actually automatically removed those parentheses okay but when we use the Turner operator we will need that but don't worry I'll show you how to do that as well okay so this handles the case if the current user is matching the user that we're editing but if we're not editing the user then all we want to Simply do is just return the current user and that way the users that are not being edited won't be changed at all we're only changing the user that is being edited hence why we have this if check right over here now there's one more thing that I want to do before we actually get to editing our users we need to make sure that we are out of edit mode because otherwise we're not really going to see our changes being reflected we'll only see it inside the input field but we're not going to see it in View mode so what I'm going to do is after I call set users I'm going to go ahead and call set is editing and this time I'm actually just going to pass it false I don't need to do what I did on line 14 where I pass in this callback function and just set it to the opposite value of the current state because every single time I click on this save button I want to exit out of editing mode and this is very common with any application when you click save that pretty much implies that you're exiting editing mode and you're done okay so let's go into our document now and let's see what happens when I click edit and I'll just change this to let's do anen deev and if I click save you'll see now the username is now anev if I click edit and let's change it to an the dev for the email you'll see that the username and the email are both reflective obviously we didn't change the username that time so it's stood the same and if I go down over here if I change the username from Mike to Mike the dev you'll notice that it only affects this user and not this user up top over here because we have this if check right over here of course if I just uh didn't check for this and I just did the same exact thing for everything and I'll just show you just as an example you'll notice that when I click save it updates it for every single user which is not what we want so that's why this check is very very important okay so hopefully this makes sense and just one more thing that I do want to do nothing crucial but I only want to show the edit the the save button when we are in editing mode so I'll just do a conditional render so let me copy that whole thing so if is editing so or if is editing is true and I actually don't need a turn operator for this I can actually do is editing and use the double and peran sign and then so only if is editing is true then it will also render this button as well and this is another react trick that you need to know because if editing is false remember that this double and perent sign this is known as a conditional and so both has to be truthy in order for this whole statement to be true so if is editing is false that means this whole conditional statement is false so this butt will not be rendered but if is editing is true we know that this bun element is going to be truthy so this whole statement will be true and that will lead to this bun being rendered and you'll see right over here when I refresh the page you'll see that when I click edit now the save button appears and if I change it and if I click save it no longer appears so hopefully all of this makes sense now very quickly let me go ahead and actually tidy all of this up a little bit so as I promised I'm going to show you how we can use a Turner operator to make this look a little bit more cleaner so what I'm going to do is let me just remove all of this right over here and I'm going to go ahead and do current user. ID equals user. ID and then if this is truthy then we're going to go ahead and return a copy of the current user while also updating their username and email and then if this condition current user. ID is not equal to user. ID we're going to go ahead and return what is on the right hand side of the colon which is just going to be current user just like that okay and I actually don't need this curly braer here so I'm going to return it and now you understand why I want to show you both instances because it can be a little bit confusing with all of these uh parentheses in the way so that's the reason why I want to show you both ways but it works the same exact way there you go all right now I'm going to show you how to delete elements from our Delete Element from State Array users array in the previous section I showed you how to update elements in an array for your state which was actually more so like replacing an element in an array but this time I'm going to show you how to remove an element from our array so that way we no longer see the element in the documents so for example if I want to delete this user right over here it needs to be removed from the document and it also needs to be removed from the actual user C itself so what we're going to do is first let's go ahead and register an onclick event listener to this delete button and let's call this callback function and what we want to do essentially is we want to update the state we want to update users to not have the user object that we want to get rid of now many of you might be used to using mutable methods such as array. splice we don't want to do that in react because remember in a react we want to practice immutability so we're not going to use array. splice to update our us array what we're going to do is we're actually going to use a method called array. filter so think of it like this we're actually going to be filtering out the element that we don't want okay so I want you to think of it like that because array. filter is immutable it returns a new array so it doesn't actually modify the original array itself which we don't want to do so what we'll do here is this I'm going to go ahead and call the set users function because we're still going to update the users State okay we still need to update the state and we do that by calling this set users function that we passed as a prop it's the same thing that we did when we were editing users so we're going to also pass in the Callback function because remember that we need access to the current state of the users so I'm going to call this current user State and remember this is an array so I can easily reference it and I can also call the filter function okay so current user state. filter so if you're not familiar with what the filter function does then you need to make sure you understand this because you're going to be seeing this in a lot of react code bases and you're going to be using this often so the filter function pretty much just literally filters out elements that you don't want okay think of it like this we don't want the element that we want to delete so we're going to quote unquote filter it out now the way that this filter function works is it takes in a call function and it's also known as a predicate function and this predicate function returns a Boolean a true or false value which we're going to end up evaluating a conditional statement anyways and this CC function also takes in up to three arguments pretty much the same thing as the map function the first argument is going to be the element in the array that we are filtering so current user state so this argument is going to be our user and then what we want to do is we want to write a condition that is going to determine what elements get filtered out so in other words we want to filter out the element that we want to delete so let's say I'm deleting the user with the ID of one then we want to filter out that specific user where the ID is one now instead of thinking of like that we should think of it like this we want to basically filter all of the users that don't match the idea of the user that we're trying to delete because the filter method returns a new array with with all of the elements that pass the predicate function okay so the way that we want to write our condition is like this I want to check if current users's ID is not equal to the users to the user that I'm trying to delete ID okay so if current user. ID is not equal to user. ID and remember user is this up top over here this is going to be the user that we are trying to delete if this is not equal then we're going to add this current user to the new array that is going to be returned okay so think of it like this if if if everything so far doesn't really make any sense think of it like this right remember that this whole filter function is going to return a new array it's going to return a new array that excludes all of the elements that fail this condition so in other words if this condition is false then current user is not going to be part of that new array that is created by this filter function okay that new array is what is actually going to be used to update the state of users so it's basically going to look like we are removing the user from the document okay so think of it like this if the user that we're trying to delete has an idea of one so that's going to be user right over here that's the user that we're trying to delete and let's say the current user it just so happens that the current user has the ID of one as well well obviously one is in fact equal to one because this check this condition is checking to see if the IDS are not equal but one is equal to one so since this condition fails then that means that this user with the ID of one is going to be excluded it's going to be filtered out from the new array okay if we get to the user of ID 2 well two is obviously not equal to one because we are trying to delete the user of ID 1 two is not equal to one so two will be part of the new array the user of ID 2 will be part of the new array of users okay and all of that gets maintained in a new array that at the end gets returned and then we're using that new array to update the state of users okay hopefully that makes sense but I promise you take some time and practice the filter function it's worth it you need to understand how this function works and not understanding how it works is going to make it a lot more difficult when it comes to updating your state and react okay so now what I'm going to do is show you how this all works visually so I'm going to go ahead and refresh the page and notice how if I click delete we deleted the user from the document if I click delete over here we deleted the second user okay so basically everything that I just mentioned that was happening in the logic of our filter function is what is happening visually but you just don't see it underneath the hood okay you're just seeing the service level of it but that is how you can remove elements from the document but really what's happening is you're just filtering out the array and you're creating a new array and then updating the states of users with the new array okay so it's not really deleting an element directly from the used array because again we don't want to do things mutably we are basically just creating a new array with a filtered out version of it so hopefully that makes sense so now I'm going to show you how we can add elements or Add Elements to State Array brand new elements to our us array and also update the state of it as well and then have it reflect on our web page so this is actually pretty simple but there are a few things that I do want to mention and stress later on especially when it comes to the unique keys that we're going to need because keep in mind that right now we're using these Keys uh we're using the user IDs as unique keys for our components but what's going to happen when I add an element and then add it to this user's State variable what is the unique key going to be right I can't just to set an ID for the user on the fly like this remember that in a typical application the identifiers the unique IDs are typically set by the database or set on the back end somehow either using a uuid or whatever okay so I will address that towards the end of this section of our of our uh tutorial so what I'm going to do is I'm going to go ahead and set up a simple form and we can actually do this inside our app component so I'll set up one real quick let's do this I'm not even going to use the form element I'll just do inputs um we'll do input and then I want to set up a label and this will be for [Music] username ID username we will need some State as well I'll do that in just a second and then let me make sure I have one for email then email okay so it looks like this I will actually add this up top over here and you know what I will yeah I'll just leave it like this for now and let's see what it looks like okay let me wrap this inside their own divs okay there we go and last but not least we do need a button so you know what actually I will wrap this in a form so that way I can put the button there okay so we have our username email and add user uh I will do this let me add a couple of breaks just so everything looks a little bit more organized okay perfect so let's go ahead and do this let's add some state to bind to our username and email fields so I'll just go ahead and keep it simple I'll just use a simple string but if you want you can use an object to encapsulate all of this but I'll just use an individual string for each one okay and let's go ahead and set the value and we will need event listeners or each one of these so let's do on change that's the event listener that we want to register basically the tech changes whenever we update the input Fields value so all we're going to do is call set username and then pass in e. target. value again this is stuff that we've already done already so that's why I'm kind of speeding through it and let me copy and paste this and just call set email okay so now when I click on add user when I click on add user what it should do is it should add it to the users array and then it should display in the document okay now let me go ahead and just fix this part where you can see that it is refreshing the page whenever I click add user that's because we have a button inside our form and we haven't overwritting the onsubmit default value so we can very easily do that by just adding this onsubmit event listener and then we can just do e. prevent default and that will ensure that we don't have the page refresh when I click on this button okay so just wanted to mention that very quickly so now what I'm going to do is this so whenever I click on the onsubmit or whenever I click on add user it's going to go ahead and Trigger this onsubmit event because we're inside our form that's just the default Behavior right so so I'm going to go ahead and conso log username and email just so you can see what this object looks like so I click add user right now or I'm sorry not object the current uh values right now it's currently empty but if I type something you can see that it appears right over here so what we want to do is we want to wrap this inside an object and then we want to add it to the array of users but we also need an ID for the user itself okay so this is the part where it gets a little bit tricky right because now you're wondering well what exactly do I use for the ID now I'm just going to cut right to the Chase and I'll explain later on why this is very important but the best thing that you can do when it comes to adding elements to the document dynamically and needing to find a way to associate a unique key with the added elements because keep in mind that these elements right over here we are assuming that these are unique IDs that come from some API and those are typically generated by the database right and an application where you need to create a list of data on the front end side that is not going to be generated by the backen at all you're going to need some unique identifier to identify each element and I've actually ran across uh I've actually ran across this problem myself a couple years ago and I've had some discussions with some other more knowledgeable people than I am and we came to the conclusion that one of the best ways to handle this is actually by using an incrementer to keep track of all of the unique IDs okay so this is what it's going to look like so what I'm going to do is I'm actually going to create some State and I'm going to call this counter set counter this will be a numeric value and I'm going to hardcode this just as an example I'm going to set the I'm going to set the default value to two because we have two elements by default currently I'm going to set it to two and then I'm actually just going to increment it every single time okay well actually I'm going to set it to uh I'll set it to three okay so what I'm going to do now is I'm going to create this new user object I'm going to set the username and email email and then I need to set the ID to be what counter is so counter will be that right over here counter will be three since that's the current default value so when we first add a user the ID of that new user added will be three and then all we need to do is just increment the counter by one so we can just easily do that by simply just calling set counter and then we want to make sure that we have the current value of counter so we're going to use the callback function and pass in that argument and then do current counter + one okay and then we're going to go ahead and we're going to call set users and then we're going to add new user to the array and this is actually very easy the easiest way you can do this is by calling set users passing in the Callback function so you get access to the current users State and and then you can just pretty much create a new array you create a new array and then use the spreader operator on the original array so this will take every element that is inside current user state which are all of these user objects and whatever has been added to it and then unpack it and then place it in a new array preserving its order and then all we need to do is we can add the new user element at the end just like this and again this does it in an immutable way without directly mutating the array itself okay and if you wanted to place the new user in the front you just put it right over here before you spread the current user State okay so hopefully this makes sense now let's go ahead and refresh our page and let's add a user so let's add Tim and you can see now it works I can add more users there you go I can even delete these users and add it again but now you'll see that the ID is five because it's preserving that counter as the ID it's using whatever the value of counter is okay now I do want to address this because a lot of people will be wondering well can I just use the index of the element in the array as the ID so what people are talking about is this so remember that the map function takes up to three arguments the first argument is going to be the value in the array itself the current value the second element is going to be the index so the current elements index okay so for example the index of this first user object is going to be zero and then this one is going to be one and a lot of people are wondering well can't I just use the index as the key and as the ID to uniquely Define these users well you can't I mean you surely could but you will run into a lot of weird issues that you won't understand why it's happening because you use the index as the key now let me actually rephrase this you could actually use it as an ID just not as a key when I say ID I mean the ID of the user object there's nothing wrong with that but you cannot use it to Key your component that you are rendering to the document just to be more precise now in a nutshell don't use indexes as your keys there are basically a lot of issues that can come across such as performance impact and a lot of bugs so just use an incremental counter especially if you are just building some kind of application where you need to add data that is displayed on the front end that has not reached the back end just yet okay because again there are a lot of examples where you need to add information to the screen via a form and you have not send that data to a server so the server can't generate a record for that data so you can't use the autogenerated ID that the server gives you as a unique identifier so in situations like this using a counter is perfectly fine just don't use the index of an array okay so hopefully this part makes useEffect Hook sense in this section of our react tutorial I'm going to teach you about the use effect hook if you've been watching you have been introduced to a hook called the use state hook which is used to define state and also manage state I'm going to teach you about the use effect hook because this is a very important hook that every single react developer must understand and be able to use inside out because the biggest thing when it comes to react is knowing how to properly use this use effect hook to perform side effects in your application because often times you will need to perform side effects in your application so first of all what exactly is a side effect a side effect is basically anything that you perform that is outside of the scope of your component or in the broader scheme outside the scope of your application itself so for example if you need to make a network request that's outside the scope of your application because once you make an API request to some external server your application has nothing to do with it it's just going to get back the response from the server itself another example of a side effect is accessing local storage which you if you aren't familiar with local storage it's basically just a way for you to store data in your browser that you can access later on another example of a side effect is being able to directly manipulate the document itself so if you want to manually update the title document if you want to manually insert an element into the document that's a side effect if you want to manually register an event listener onto your document such as whenever the browser is being resized or if the user is scrolling these are examples of side effects there are a bunch of different side effects that you'll come across these are just common examples that a lot of developers often need to tackle on so I'm going to teach you all about the use effect hook how to properly use it I'm going to teach you about the different behaviors of this use eff hook so that way you fully understand how to properly use the use effect hook so I know right now inside our app component we have a lot of stuff going on and I want to make this as simple as possible because when there's just too many things on our screen inside our code it can be very overwhelming to just track every single thing so I'm going to make this very simple I'm going to remove uh this username and email I'm going to remove all these users you don't have to remove this if you don't want to I just think it's better for us to remove this just so that it makes it easier for us to see what's going on instead of just tracking everything that is on our in our code so what I'm going to do is I'm going to keep this counter State and I'm going to set this to zero and I'm going to create a button and I'm going to go ahead and give this button a text called click me and then I'm going to register an onclick event listener on this button and every single time we click on this button I'm going to update the counter by one so this will basically track the amount of times we as the user clicked on this button so let's go ahead and update the state just like this and then I'll go ahead and display that text to the user you clicked the button counter times okay very simple stuff just to show you how this is going to work you can see over here we have our text currently it says you click the button zero times when I click this button for the first time it'll update and each time I click on it it's going to basically by one very straightforward stuff okay now what I'm going to do is I'm going to go ahead and import my use effect hook now remember that the use effect Hook is also a function so let's import that first from the react package and the way that we're going to use the use effect Hook is like this so we're going to go ahead and just call use effect like a regular function and this use effect hook takes up to two arguments the first argument is mandatory it is known as a call back function or an effect call back okay so this is just going to look like a regular callback function and then the second argument is optional but it is very crucial to understanding how to properly use this argument okay the second argument is an array or better known as your dependency array or a dependency list it's basically just an array okay I'm going to explain more about this uh in just a second but first what I want to do is I want to Omit this because I want to inside my callback function of my use effect hook I want to basically just directly manipulate the document and there are a lot of different ways that I can do this I can access local storage I can update the title of the document so what I'll do is right now you can see that the title of our document is V plus react that's just a default title and what I can do is I can just set the document title like this to react tutorial and so what's going to happen happen is whenever our app component is rendered whenever it's mounted to the document our use effect Hook is going to go ahead and invoke this callback function okay now remember what I said based off of how you set up your use effect hook if you have the dependency array or not it's going to contribute to the behavior of your use effect hook and how it calls your functions and how many times it calls your functions so basic basically right now in this current state every single time my app component is rendered and rendered it's going to go ahead and invoke this callback function okay so just so you know that there are different life cycles of a component so for example when it first renders to the document after it renders and then when it needs to unmount from the document okay so in the initial stage we're mounting the component we're rendering the component to the document and then in other situations our component May perform a render of itself and a lot of things can trigger a rerender one common example is whenever your State updates your component can render and I'll show you that in just a second so Watch What Happens here so when I refresh the page you can see that the title is updated to react tutorial and it does it so fast that you don't really notice the update happening in real time because it's just happening like instantly okay but I want to show you what happens when I console log this message rendering if I refresh the page you'll see that it's going to render it's going to log twice now this is because we are in strict mode which is what is enabled by default you can actually turn us off by just removing this react strict mode right over here and then you can see now it renders once okay you don't have to turn it off but just know that you can if you want to by default in production strict mode is off okay so when I refresh the page you can see that it is going to do its initial invocation of the Callback function now watch what happens when I click on this button you'll notice that every single time I click on this button this rendering is being logged to the console so that implies that this callback function this effect callback is being invoked because obviously in order for this console log to be logged to the console it has to have this function being called itself now why exactly is our callback function being invoked so as I hinted earlier we have some State over here we have a counter every single time I am updating the state of counter what happens is react is going to unmount and then rerender the component reflecting its new state okay so over here you can see that I am updating the state of counter so it's going to go ahead and render app and whenever we render app remember what I said earlier when app is rendered by default it is going to go ahead and call the Callback function of this use effect hook and that is why this console log is being rendered to the document okay hopefully that makes sense I can even go a step further and I can actually concatenate this react tutorial title with the counter and then that way the title will tell you how many times it was updated okay so 18 times 23 times etc etc you get the idea so hopefully this makes sense each time I make an update to my state in this current usage of the use effect hook where I don't have any dependency list or dependency array added At All by default it is going to call this callback function every time our component rerenders okay useEffect Dependency Array now I want you to see what happens when I add the dependency array remember this array is optional you don't need to have this but just know that depending on how you use this dependency array whether you omit it or add it to your use effect hook or if you add certain elements to this dependency array which I will teach you about that in just a second this will change the behavior of how your use effect hook works so let's show you this example of what happens when I add an empty dependency array to my use effect hook okay so I'm going to go ahead and refresh the page now you can see that initially what's going to happen is it's going to go ahead and call the Callback function of my user vub okay and it does it twice because that because we're currently in strict Noe but watch what happens when I now click on the click me button cause it to update the state of my counter okay I'm clicking the button but notice how the rendering function or I'm sorry the rendering is not being display to the console anymore and you can see that the title still says react tutorial zero okay notice how that is happening right now because I added my empty dependency array if I remove it if I remove it you can see that now it is going to log rendering every single time I click on the button why is this the case so when you add a dependency array and more specifically when you add an empty dependency array to your use effect call what happens is the Callback function the effect callback is only going to be invoked one time only which is when your app component initially renders and any state that is updated is not going to cause a call back to be inv or it's not going to cause the use effect call back to be called okay and it's pretty evident over here because I am making updates to my counter State variable but the user effects call back over here is not being called again and again and again that's because I have an empty dependency array okay now I will mention right off the bat this is a very useful situation when you need to make an API call as an example so let's say if you are trying trying to fetch the user from an API and you want to render it to the document and you don't want to refetch the user every single time you're making updates to the state then you would want to have an empty dependency array added to your use effect call okay so generally this is very important it's very common when you only want your use effect hook to call the Callback function one time only now the next important thing to understand is the dependency AR and what we can add to our dependency array so as I mentioned earlier not having the dependency array will cause your use effect call back to be invoked upon every single render adding an empty dependency array will only allow your call back for your use effect hook to be called once only no matter what state variables change but there are situations where you do want your use effect call back to be invoked whenever your state is being updated now let's say I do in fact want the use effects call back to be invoked whenever the counter State variable or any state is being updated what I want to do for this dependency array is I want to specify which state variables are a requirement for this call back to be invoked so this is the reason why it's called a dependency array because the use effect hook depends on those State variables in order for them to change to cause the Callback function to be invoked okay so for example by adding this counter State variable to this array what I'm basically doing is I'm saying okay whenever a change occurs to counter call this callback function only when counter changes so now watch what happens if I refresh the page and if I click the click me button you'll see that when I click on this button it's going to go ahead and call the call back function again okay if I click on it twice or if I click on it a second time it's going to call the function again and again and again and again and again and this is the behavior that we wanted or the original behavior that we had when we didn't have our dependency array okay so hopefully this makes sense now just to show you another example perhaps you don't want to necessarily use the counter State variable as a dependency you may want to depend on a different state variable so let's do this let's say we want to click on the button x amount of times okay and then we want to have a synchronize button to basically synchronize the state to show us exactly how many times user clicked on the button itself okay so what I'll do is this I'll create a variable another saate variable called sync set sync and this will just be a simple Boolean value that will just all alternate between false and true okay and this is a very common approach to uh being able to detect whenever something is occurring so what I'm essentially doing is I want to add sync as a dependency to this use effect hook okay and then what I want to do is this I want to add another button and then I'll have the text be sync and then whenever I click on this button I'm just going to go ahead and just update the state of sync I'm I'm basically just toggling it so I'm going to call set sync and then uh current I'm just going to set it to the opposite value of it so the basically if sync is true it's going to update to false if sync is false it's going to update its true so we're basically toggling between true to false false to True okay and whenever I do update sync what's going to happen is in or in order for this use effect hook to be invoked sync needs to change okay so Watch What Happens I'm going to go ahead and click on click me as many times as I want now keep in mind that the counter state is still going to update and it's still going to display in the document just fine that's that's normal but in order for my use effect hook to invoke this callback function and update the documents title manually I need to make a change to the current state of sync in in order for this call back to be invoked so watch what happens when I click on the sync button you'll notice that when I clicked on the sync button we logged rendering to the console and then you you'll notice that the title was updated from re uh it was updated from the previous one to react tutorial 20 I can refresh the page and show you again okay so right now the Callback function of the use effect Hook is called one time upon render that's default Behavior okay react tutorial zero so in the current scope of this callback function counter the value of counter is currently zero that is why it says react tutorial zero I'm going to go ahead and click on the button 10 times and you'll notice that the title has not changed at all but the moment I click on the sync button the title now is changed and you can see that rendering was logged to the console okay so hopefully this shows you how powerful this dependency array works it's only going to go ahead and invoke this callback function whenever specific State variables are updated one thing that I do want to address is you'll notice that we have this linting warning over here and it's telling us that we're missing a dependency called counter you'll notice that if I add counter it just goes away the reason why this linting warning is occurring is because basically whenever you're using a state variable inside the Callback of a use effect hook react wants you especially if you have a dependency array react wants you to add that as a dependency why because you're literally using a state variable that could possibly change throughout the lifespan of your component it could possibly change okay so if that state variable changes we want to make sure that when we call our use effect callback function that we have the latest value of counter okay because right now over here my omitting counter I can update counter as many times as I want but this use effect hook the scope of it we'll never really know okay and so you might run into some issues sometimes you can get away with running into some issues but generally you shouldn't use State variables inside a USC H if you don't intend to add it to the dependency array itself okay now obviously by adding this counter variable to my dependency array it would not give me the behavior that I originally wanted but this is essentially how you would get rid of that warning issue you could also just not use the counter at all and you can just leave it like this and that would be perfectly fine so there are different there are many different ways that you can go about this but I did want to address this issue Fetching Data Example okay so now I'm going to show you an example where we can fetch data from an AP pii which is another side effect that you will often need to perform in your react application because whenever you're building an application you typically want to serve data to a client you want to render that data somehow to the user and where does that data come from a server an API you name it so I'm going to use this online server this is free and they have it set up with mock data so I can fetch some posts I can fetch some comments I can fetch some albums what whatever it is I'm going to show you how to make these simple HTTP requests okay let's go ahead and get started so inside my code now one thing that I also want to mention is that when it comes to the use effect hook you can have as many use effect calls as you want so for example I can set up another use effect hook right down over here and of course this will call its own callback function another thing that I should also mention is that use effect hooks the callbacks are going to be called in order that they are implemented so for example this use effect hooks callback is going to be invoked first and then this one and then any other subsequent use effect hooks that you may have after the second one will be called afterwards so they are in order okay so what I'm going to do is I want I'm going to go ahead and use the default fetch API that is built in to our browser API to get this data from this Json placeholder server so all you have to do is just type Fetch and you'll see that it pops up right over here and we need our URL the server that we are going to fetch the data from now again if you're fairly new to front end development and you don't understand the concept of fetching data or retrieving data from a server which I assume most people who typically start off with front-end don't really have any backend experience let me briefly explain what's going on so This Server this online server is basically just going to serve data to any client that wants to make requests to it so you can see over here they have a couple of endpoints that they already set up so I'll show you a simple one we have this users endpoint right over here and we can make HTTP requests okay so that is the protocol that we are using and the specific method that we would be using is a get request method to get this data because we're only trying to retrieve this data and serve it in a readon mode we're not trying to create data or update data on the server side so I'm going to go ahead and take this URL right over here and I encourage you to do this yourself as well take this endpoint or any endpoint that you choose to use and you're going to paste it right over here as an argument for this fetch function okay that's going to be the first argument to this fetch function is the server URL that you want to retrieve the resource from okay so in this case I'm going to retrieve this users resource which is going to give me an array of objects which are specifically users okay so now with the fetch API we do need a second argument actually we don't really need this but I will mention this just just for the sake of it because when we show examples of making post requests you will need to know how to set up this second argument but this second argument allows you to set up options for your request so by default the request method is going to be a get request which means that you're going to get data which is what we're going to do so I don't actually need these options but what I'll do is I'll set the method to get just to show you how this happens and if we were making any post requests where we are sending request bodies or even a put request or patch request which I'm sure that this terminology might be brand new to you all then we will need to set a request body property which is the body property itself and then this is where you would actually specify what key value pairs you want to send to the server so if I wanted to send a username I would specify that in this body object now obviously we're not going to be sending any data at all so we're just going to leave it like this okay so now what I'm going to do is I want to make sure that after I fetch the data I am going to be able to retrieve the data from the response okay because when you fetch dat data from some server you're basically requesting the server for that data and then the server is going to send back a response now in this situation we're going to get a response back which is an array of users and we need a way to actually handle that response okay so before I do any of that I do want to show you the API call occurring in the browser so what I'll do is I'm going to go into uh my application over here I'm going to refresh the page and I want to show you the network tab this is a great tool to inspect API calls or any API calls any network calls that are happening on your client side application so let me zoom out a little bit so right now I have it filtered out to fetch xhr which basically these are just API requests to some server and you can see that right over here it is making two API calls and remember what I said earlier that your use effect tooks are going to be invoked twice which because we are rendering the component twice it's going to cause our use effect callback functions to be called twice as well because every single time we render the app it's going to go ahead and invoke our use effect hook at least for this one right over here so you can see that it is definitely calling this API if I uh expand this a little bit you can see the request URL is this URL right over here the exact one that we pasted into this argument over here and then you can see that the request method is a get request and then the status code is a 200 which just basically means it was a successful response from the server and there's a bunch of other things we're not going to really worry about that right now and then if I click on preview this would give me a preview of the data that was sent back from the server you can even you can even just click on response to see the par version of this okay so hopefully this is straightforward now as I mentioned couple minutes ago that we want to handle the API call itself because right now we're just calling fetch but we're not actually handling the return value from Fetch itself okay so one thing that you must know is that fetch is going to return a promise now if you're not familiar with promises you definitely want to brush up on understanding what promises are in JavaScript that is actually I would say a requirement a prere when it comes to building any application in JavaScript but basically promises have States they have a pending State they have a fulfilled State and then they have a rejected State okay so when I call this fetch function it's going to return a promise and that promise will be in either one of three states so by default it's going to go ahead and call this API and we need to make sure that we properly handle this promise okay so by not handling this promise it's always going to stay in the pending State even if the API call fails we need to make sure that we properly handle this promise to get it to the correct status so that way we know whether or not the API call succeeded or if it failed okay so in order to handle this promise there's one of two ways I'll show you both the first way is you can use do then so after you call any function that returns a promise the promise object itself is going to have this then method or or it will have catch or finally so it's very similar if you've used a try catch Clause before or try catch finally so when you call do then this is basically handling the promise when it resolves which resolving A promise is actually a good thing which means that the promise succeeded okay whatever whatever function uh that it was invoking underneath the hood it succeeded it was in a resolved state which typically means it's a good thing so that means that the API call succeeded it returned a status code of 200 with our data so by calling the then method what we need to do is we need to pass a callback function now this callback function the argument that we're going to pass in is going to be the data that is resolved from the proms itself so this is actually how you access the response from the API so I'm going to go ahead and call this response okay and for now I'm not going to do anything special I'll just console log response okay and I want to show you what this looks like because we know that this API call is succeeding so I'm going to go to the console and you can see already that right over here we have our response object being log remember whenever whenever our app component renders it's going to go ahead and invoke our callback functions for use effect at least once okay so over here we can see that this callback function was invoked and you can see that right over here it is being invoked twice it's calling the API twice because of what I said we're in strict mode and that's fine so you can see that the response is logged twice that's okay and then you can see that the status is 200 which is good means a successful response from the server and the fact that this response object is defined or the fact that we're even in this scope of our callback function just shows you that the promise resolved the API call was successful otherwise we would be in the catch part which I'll show you in just a second so you can see if I actually click on body right over here maybe not body but there should be I guess I guess it maybe is body but we need to parse the data that's okay so here's what I'll do we actually need to parse the data because this is just a response and we need to actually get the data from the response object itself I'll show you how to do that right now so what I can do is I I can actually just return response and then call this Json object this will actually return a promise as well so return response. Json this returns a promise as well and then we can actually call then again because when I return response. Json this would also return a promise and I can actually handle that Promise by calling then again right over here and whatever value that promise resolves can be passed into this callback function over here so in this part over here the actual argument is going to be the actual Json data so if I show you what it looks like right now in the console you'll see that right over here on line 20 which is what I am logging over here this is the actual Json data the Json array that is returned from the API itself okay we just needed to make sure that we parsed the response by calling response. Json and then handle that promise again by calling that then okay if this is all brand new to you it might be a little bit confusing at first but I promise you that if you just read up on promises and practice them it'll make a lot more sense okay so you can see that I can see all of my data right over here and I can access it however I want I can render it to the document I can do whatever I want okay now I want to show you a situation where the API may fail so let's say for example if I just uh added this incorrect API endpoint right and if I refresh let me go to my network tab if I refresh you'll see that right now it's giving me a 404 which means not found and that's because the API endpoint is not found now because we are trying to fetch an invalid endpoint what's going to happen is the fetch function when it Returns the promise the promise itself is going to be in a rejected state after we handle it so it's not going to go into the then callback function call it's going to go into the catch function call okay so this is how you can perform error handling so what I can do is I can pass in this error as an argument to the Callback function for catch and I can actually just log the error as so like this and then if I refresh the page you'll see that uh let's see if it logs anything doesn't seem like it will log anything it seems like the error object is just empty but uh what I can do is I can actually just console log invalid endpoints and that should be logged right over here uh let's see maybe not I guess maybe not I guess if I guess the way that fetch works is that it doesn't actually reject the promise so that's a little bit strange on why it does that but um it should it should actually log some error so I actually just Googled this and it seems like the fetch API does not reject the promise if the API returns a 404 which I think it should in my opinion but it doesn't so that's okay but I'm pretty confident that if it returned anything like a 401 or a 403 status code which is typically has to do with uh the user not being authenticated it should reject at least in my opinion it should but if you use a different API Library such as axios for example typically different API libraries will handle errors differently but I I know from experience axos will in fact uh reject the promise so it will go into this catch block over here if the API endpoint isn't valid but even then when you handle the API response this is exactly what you want to do using then and catch now I'm going to show you the other way where instead of using then. catch we're going to use a combination of a tri catch block as well as async and AE okay now if you're not familiar with the async AE syntax you definitely want to make sure you learn this because you will be seeing this often as well in react code bases and even some examples of documentation and tutorials will imply that you already know how async in a way works but basically what I'm going to do is I'm going to remove all this okay and I'm going to I'm going to remove this object over here because we don't need this object right now because by default fetch will default to a get request and that's okay let me remove this extra S at the end so what I'm going to do is this first I'm going to go ahead and create a function inside my user effect callback function and this function is going to be an asynchronous function okay so I'm going to go ahead and call this function fetch users and I want to make sure in front of this function keyword I add the async keyword okay literally just added the Asin keyword in front of my function makes this an asynchronous function now all this literally means is it returns a promise and it allows you to use the await keyword inside the function itself okay now why this is important is because remember our fetch function the fetch API this function itself returns a promise okay now there's another way to handle promises instead of using the then. catch syntax we can actually use the await keyword and the way that it works is all you do is you use the awake keyword in front of any method call that returns a promise so for example our fetch function it returns a promise so what we can do is we can add the await keyword in front of this fetch function call and what this does is it basically says okay wait for this promise to resolve or reject and then proceed on with the rest of our logic with the rest of our code okay okay so in other words it kind of like blocks the rest of your code until this is complete okay until it goes from the pending state to either resolved or I'm sorry either fulfilled or rejected we typically want to pair this with a tri catch block because it allows us to perform error handling okay so what I'm going to do is I'm going to await this fetch call but I'm going to go ahead and make sure I sign this to a a variable called response and now this response variable is going to be the actual response object itself not a promise because remember fetch returns a promise when we await any method call that returns a promise you get the actual resolv value if the fetch call fails it's going to go to this catch block over here and then you can handle the error accordingly so in other words you don't get the actual resolve value okay so let's go ahead and paste our URL again so let's go back over here copy that let's paste that URL right over here and remember that we do need to do an additional step where we need to actually call response. Json to get the actual Json data so I need to go one extra step and call response. Json remember that response. Json also returns a promise as well so if I don't await this promise if I don't if I don't await this this Json call you can see that if I hover over Json the data type of my Json variable is a promise but the moment I add the a keyword in front of my response. Json method call the value of Json is no longer a promise it's the actual resolved value that the promise gives you when the when the promise f is fulfilled when it's successful okay this is very important to understand like I said because you're going to be dealing with this often especially if you're building Dynamic applications that fetch data which is very common so I'll go ahead and just conso log this variable and then I'll console log the error object down over here okay and then now what I'm going to do is I'm going to go ahead and inside my use effect hook I'm going to call fetch users but I'm not going to use the await keyword first of all I can't because I'm not inside an asynchronous function if I try to you're going to see that's it's going to give me an error because it says cannot use keyword a out outside an async function now you might be wondering well couldn't I have just added the async keyword in front of this callback function now you actually could but you're going to get this linting warning and the reason why it tells you this is because it has everything to do with preventing raise conditions so that's why they don't recommend you make the Callback function of the use effect hook an async function okay so that's the reason why we did it this way and in fact this is actually what you would see in an example on stack Overflow or on any uh help website that is asking how do you fetch data properly inside use effect hook the idea is you create a wrapper function and then you just call that wrapper function like this okay so again this is just a very Bare Bones simple example for absolute beginners in a more advanced scenario You' typically want to make sure you handle the situation where the request fails we're not going to get into that right now but typically you want to use libraries such as axio with react query cuz those libraries handle that kind of stuff for you okay but uh what I'm going to do now is I'm going to leave it like this and I'm going to show you exactly how this works so I'm going to go back to my tab over here I'm going to refresh the page you're going to see that my data uh well the users's endpoint was called and you can see that everything is successful on line 19 where I am logging this Json variable you can see that I have my user data now notice if I were to not if I were to remove the await call look at what is actually logged in the console you'll see that it logs Promise This Promise object and the status is pending okay the status is pending okay so hopefully this shows you why you need to make sure you handle your promises accordingly either by using then. catch or async AE okay now this next thing that I'm going to show you is not really an advanced or intermediate topic it's a very simple AbortController concept to understand so I do want to show you this so it has to do with what I mentioned earlier about uh handling the request when it either is supposed to be cancelled or if the component is unmounted because let's say for example let's say if we are rendering our app but then something causes the app to unmount maybe the state is updated whatever it is we don't want the request to go through we want to actually abort the request okay so what we're going to do is we're going to use something called the abort controller and it basically allows you to control the request so you can have it be aborted you can basically cancel the request if it needs to be okay so what I'm going to do is inside my use effect callback I'm going to go ahead and create an instance of the abort controler CL class this is a built-in API so I'm going to do const controller equals new abort controller just like this whoops just like that okay and then the important field that we want is I actually want this signal field right over here okay the signal field I'm going to show you how we're going to use this field okay but basically this is going to give you the abort signal property and it basically gives you information about the aborted request if it is aborted okay now what I'm going to do is when I make my API call so I'm when I call fetch we want to pass in that second argument that object okay but this time we want to set this property signal in this object and then what we're going to set it to is controller. signal okay and this is basically going to communicate with the request if the request needs to be aborted or not okay so we're going to leave it like this and then what I'm going to do is inside my use effect hook at the end over here and I didn't actually cover this in the previous section when we first talked about use effect hook but I'm going to talk about it right now so your use effect hook has uh has current stages right when it first renders the component your use effect Hook is called but then when your component unmounts when it kind of like UNR from the document there is a stage known as the unmounting phase or the cleanup phase and this is basically where you want to take care of either cancelling your side effects such as canceling API requests can uh unregistering event listeners from the document because you no longer useEffect Cleanup Function need them running in the background and leaving those events registered when you are actually not needing them could could potentially cause performance issues and lead to memory leaks so you want to make sure that you handle this case all the time whenever necessary so the way that this is going to look like is this your use effect callback actually allows you to return this callback function right over here and this callback function is all of the logic that you want to perform to uh handle when your component unmounts so in a situ in a situation like this when my app component unmounts an example of that would be if we update some State and it may cause the component to render it goes through the unmount stage first and then it renders the component again so when that happens we definitely want to make sure we are canceling any API requests because those API requests are no longer valid they are stale and we don't care about them anymore so they the way that we can do this is we can reference our controller instance and just call the aborts method like that okay so I'm going I'm going to go back to my page and just watch this if I refresh you can see that right over here it's pretty evident what's going on okay so you'll notice that the first API call was cancelled because I have my abort controller cancelling or aborting the API call but notice how the second one is successful you might be wondering well it's pretty obvious why this is happening and maybe if it isn't obvious I'll explain so remember what I said we're in strict mode right now so by default our use effect Hook is going to be invoked twice because or I'm sorry our use effect call back is going to be invoked twice because the app is rendering two times okay that's going to cause our use effect hook to render one time for each render of the app okay now it renders once but then it aborts this API request because the component unmounts and then the component renders again but the component doesn't get unmounted the second time okay so what happens is on the second time it's going to go ahead and actually make the API call and since we're not unmounting the component this call back function down over here that we are returning this cleanup function is what it's called never actually gets executed okay so hopefully this makes sense the cleanup function is called the first time because we are unmounting the components okay then the component is rendered the second time and then this cleanup function is not called the second time okay but if there was an instance where we were in fact going to go ahead and unmount the component and based on I guess the status of the controller itself based on that it would then tell us if we needed to cancel the request or not and actually if I were to conso log controller and then if I were to conso log the signal this would actually give us some information about the request if if it has been aborted or not so you can see over here uh right over here it says abort signal aborted false so it was not aborted on the second time but the first time it definitely was it it definitely isn't in fact I could probably console log the signal down here and it should tell us that it was aborted so you can see over here in the cleanup function in the scope of this cleanup function over here when I after I abort the API request the signal has this object over here and you can see that the aborted property says true which basically tells us that the request was in fact aborted okay so again this is nothing crazy to understand it's just something that I think is worth noting but like I said when you use librar such as react query they take care of this stuff underneath the hood for you so you don't need to worry about it but since we're not using react query right now I think that is more for an intermediate level or maybe once you get used to understanding how API API requests work then you should get to using react query okay but hopefully this part made sense now before we do move on from POST Request Example Network requests I do want to show you an example where we can make a post request to the server so a post request if you're not familiar with it is the type of request that you would make whenever you want to create some kind of record or resource on the server side a realistic example of this is let's say for example you want to create a new user account on some platform so what you would do is you would sign up you would enter your display name your username email password all that kind of stuff when you click on the register button it's going to submit your data to a server via a post request okay post basically is just a different request method so when it comes to network requests via HTTP you have get requests you have post requests you also have put in patch for updating a record on the server side there are a bunch of different types of requests okay so you basically make a post request you send that data to the server side via the request body and then the server side will take care of saving that information on the database okay so what we're going to do is we're going to set up a very simple post request where we are going to create a post like a literal post like a blog post okay we're going to use the Json placeholder server as well because they do have a post request endpoint that we can take advantage of it doesn't actually add new posts on their endpoint it just it probably uses some kind of mock service worker or something behind the scenes to make it simulate adding posts to the record to the existing records so we're going to do that so what we're going to do is I'm going to set up two form Fields because this endpoint is going to require I'll show you it's going to require a title and a body as well as a user ID the user ID we're just going to hardcode that but the title and body will have ourselves type information into some text fields and then we'll submit that to the server okay so here's what we're going to do first let's define some State I'll go ahead and call this post um I'll call it blog post data set blog post data and then this will basically be an object that is going to represent what we type into the form Fields we're just encapsulating everything in a single object instead of defining it as individual strings or state variables that are strings so we're going to need our title which is going to be a default value of an empty string and then our I think it's the body let's double check uh body up and that's going to be an empty string as well okay and then now let me go ahead and set up to form Fields so let's set up a form we're going to need a label and we're going to call this label title and let's set up the input field and then the ID of this is going to be title it's going to match whatever this HTML 4 value is so title title and then let's go ahead and set the value to blog poost data. tile so we're basically binding this uh this state objects title field to this value we need to make sure we also handle the onchange event so every single time we type into our input field or if we paste something or if we cut the text from the input box that's going to trigger this onchange event so we want to make sure we update the state and I showed you how to do this in previous sections when we covered I believe it was the register form yep the register form so I showed you how to update the state when it's an object so this will be a little reminder we're going to call the set blog post data function this updates the entire object itself but we're going to do some JavaScript magic so first I'm going to pass in this callback function to get access to the current state of blog post data so I'll just call this current blog post data and I'm going to create a new copy of the current state like this so I'm going to use the spreader operator on the current blog post data object and then I'm going to explicitly override the title because that is what we are updating and the value of title will be e. target. Val because that is what we are uh that is the actual value of the input field okay so every single time we type or paste something or just cut the value of the input box it's going to trigger this onchange it's going to go ahead and call set blog post data and then update the object but it's going to specifically update the title field okay we're going to do the same exact thing for our body so let me wrap this in a div and let me just go ahead and just copy this whole thing paste this and just change everything up so I'm just going to call this body call give the ID body and then just call this label body and instead of blog post data. tile it'll be blog poost data. body and then then we're going to go ahead and do the same exact thing when we call said blog post data but this time it's going to be body instead of title okay so now if I go back to over here I can easily modify the title or the body and then if I go to my console log and I'll just log it to the console real quick just to show you that it is in fact being updated correctly so hello world is the title and then welcome to my app is the body this is the data that we're going to send to the server side now there is obviously one more field the user ID we don't have an actual user so we're just going to hard code this so what I'm going to do now is I'm going to add a button that's just going to have the text of create post so I'm going to add that button inside this form element so we'll have the button and we'll just call this create post and again we've done this several times already so this should be familiar if you've been following along with with every section of the tutorial if not that's okay what I'm going to do is since this button is inside the form itself all we need to do is just handle the onsubmit event because that is triggered when I click on this button itself and we're going to pass the Callback function and then the Callback function for the onsubmit I'm going to pass in this argument the event object and we're going to call e. prevent default this will ensure that the form when I click on this create post it doesn't cause the browser to do the default Behavior which is going to actually refresh the page well it actually tries to send the data to the server but it does refresh the page okay and then what I'm going to do when I click on the button is this it's going to call this function it's going to call this callback function and we want to send the data to the actual fake Json server so we're going to make a post request using the fetch API so similar to what we did in the previous section of this tutorial where we made a get request EST but this time we're making a post request so I'll show you how to do that so first let's do some validation let's make sure that both title and body are not empty strings because we don't want to send empty data to the server so I'll do this if blog poost data. title and blogpost data. body so remember that a string an empty string is a falsy value so both of these strings need to be actual it needs to be non empty values for this condition to evaluate the true okay so if at least one of these strings if they evaluate to a false Val value okay so in other words if one of them is an empty string this whole condition will evaluate to false which means that this whole block of code will not execute and that's what we want we want both title and body to not be empty okay so we're only going to make the API call if title and body are not empty so if that's the case I'm going to go ahead and use the fetch API and what I'm going to do just to keep things simple I'm going to actually just use the then and catch syntax to handle everything instead of just using async AE so I'm going to do Fetch and then we're going to need to specify the Endo so that's going to be this URL and then SL posts which is the Endo right over here so basically this is the base URL and then this is the end point that we are making the request to SL posts okay and then we need to make sure that we pass in the second argument which is going to be our request uh options so we want to make sure we explicitly set the method to post because remember by default fetch is going to default to a get request but since we're making a post request we need to actually explicitly set that and then we also need to make sure we pass in our request body and remember that the request body is basically an object that you are going to be sending well you're not actually sending an object um it may look like an object service level but when it goes through the whole network it's actually serialized but in the end it's actually going to result into an object okay the way that the server parses it will end up being an object so you want to always make sure that you have your request body right over here and what we want to do is we just want to set the key value pairs that we want to send to the server so the server is going to expect three properties in our object it's going to expect the title body and the user ID so the user ID like I said we're going to just hardcode this we'll just set it to one and then we are going to go ahead and set the title and the body like this okay whoops sorry about this title is going to be blog post data. tile and then body will be blog post data. body just like that okay and that should be it so before I do anything with handling the promise let's actually make sure that the network request is succeeding we can verify that in the network tab so I'm going to refresh the page and watch what happens when I type uh hello world and then hey let's click on create post okay so when you look at the network tab you can see that a request was made to the server and I know that this request succeeded because the status code is green well it's a 2011 status code which is a successful status code and it's green and 2011 basically means that you created the record successfully okay which is good if you look at the payload you can see uh an object was sent if you look at preview uh so right now actually we have a problem because if you actually look at the payload this is not what it should look like and the preview of the data it should actually return the actual entire object with the title in the body that we uh that we sent but right now it's not actually returning that and you can also confirm this if you look at the documentation of this uh mock server that this is actually what it's supposed to return now the reason why this is happening is because right over here for our body property it's not actually supposed to be an object it's supposed to actually be a stringified object itself so the easiest thing that we can do is we can actually use this json. stringify method and then just pass in the object itself so what this will do is this will literally just convert the Json object from an object to an actual string and that is what we need to do in order for this API request to properly create the data okay even though the request succeeded the contents that we send was not correct now I'm going to go ahead and refresh the page and I'm going to show you what happens now so let's do Hello World create post so the request succeed Ed now notice how this time if I look at the payload you'll see that it says body title and user ID if I look at preview we have 101 uh not really sure why it is still uh maybe let's see oh you know what I forgot to add one more thing perhaps I need to set the content type to application Json maybe that's what it is so that's good that we caught that so often times when you are making Network requests the server needs to know how to interpret data and how to parse the data as well so when you set these headers such as content type that allows you to specify okay this is supposed to be Json okay so let's go ahead and just add this part real quick and let's paste that over here just like this and now we should not have any issues we still do need the stringify though so if I go ahead and refresh let's just type some random stuff so now yep there we go we have the correct response sent back from the server we have the correct preview and the payload is perfectly fine and if I were to remove the stringify part and just return or just sent this itself okay you can see we get a 500 error code and uh this time I can actually handle that correctly in the catch block okay so let's go ahead and just handle our our uh our success and errors so when the response is successful we're going to get a response back and all I'm going to do is just call response. Json because I want the actual Json object that was sent back from the server and I'll just go ahead and say success and then log the data if there is an error we'll just go ahead and catch that and then I'll just console log the error like this okay again a very basic service level example of how to make a post request now if I go ahead and refresh the page and if I try to do this you'll see now we actually are able to properly handle our errors online 33 it is logging syntax error unexpected token s uh so yeah you can see that it is ering out because of this object over here okay now let's go ahead and just add that json. stringify call again to this object and we should no longer get that error you can see now it logs success and then the actual response from the server when we successfully created the record so yeah hopefully this makes sense I don't think if you actually were to call the Post endpoint it would actually show you um the actual added post so don't worry about that though it's okay because like I said the whole purpose of this example is to show you how to actually make a poster request so now that you know how to do this when you actually have a real API that you're going to make post request to you know how to do that you know how to paste the URL you know how to specify the method request type you know how to parse the Json object that you want to send into a string by using json. stringify and then you know about the headers as well so hopefully this part made sense Creating Custom Hooks now before I move on entirely from the use effect hook I did also want to show you a couple of other examples and some other patterns that you can use the user effect hook for so as I mentioned earlier whenever you register event handlers directly on the document itself that is also another known example of performing a side effect and it's not not that it's a bad thing because oftentimes you will need to do that so an example would be if you need to detect when the user is resizing their viewport their browser then you may want to perform some kind of action I'll show you how to do that using a use effect hook so what I'm going to do is I'm going to go ahead and call use effect and then pass my callback function and I only want to have this callback function executed one time and it would make sense because we only want to register the event listener once on the document it wouldn't make sense for us to register multiple times because there's just no need to so what I'm going to do is I'm going to use an empty dependency array this will ensure that my call back executes one time only no matter how many times we update our state if there is any state if we update it it's not going to cause this call back to execute again and I showed you that in earlier examples of the use effect H so what I'm going to do is I'm going to add an event listener on the window object I'm going to do window. addevent listener and there are a bunch of events that you can register directly onto the window itself the one I'm going to do is let's do resize so this will of course occur whenever you resize the browser window and what I want to do is I could pass in the Callback function this is known as a listener function because it literally listens to the event and it's going to be what is used to handle the events whenever it happens okay so instead of actually just passing the Callback function like this I'm actually going to go ahead and create a function a named function specifically so I'm going to go ahead and call this resize event handler just to be more verbose with my variable names and then I'm going to go ahead and pass it like this now the resize event handler does take in an argument you can even see that in intell sentor right over here if I do this you can see that the event itself is a UI event so we're going to go ahead and do e and I'll just go ahead and console log window viewport resized okay and I'm going to go ahead and go into my browser now and I'm going to show you what this looks like so let's refresh the page notice how if I change the size of my viewport you can see that it says window SL viewport resize which implies that this resize event handler function is in fact being called every single time it detects a resize of the viewport of course if I were to let me do this let me kind of uh resize the browser itself I mean resizing the browser is going to cause the view port to resize so it's going to trigger the event regardless we can see that the view is changing and then that event is being triggered okay now what we want to do is whenever the component unmounts because it could possibly unmount we want to make sure that we are unregistering this event from the window itself because if we don't do that and the and the component unmounts what's going to happen is that if the component mounts again which could possibly happen especially if you're performing something like a conditional render it's going to cause a another event of the same instance to be registered again so in other words when the app component remount your resize event is going to be registered again and again and again okay so to avoid registering the same event multiple times what we want to do is we want to use the cleanup function inside our use effect callback now this is something that I did show you earlier when we first talked about use effect hooks but in case if you missed that the cleanup function is basically this function that you can return inside the call back itself so it looks like this return and then this function right over here and this is your cleanup function this function is called whenever your component unmounts okay which happens whenever the component no longer needs to be rendered anymore no longer needs to be in the document anymore so it will just unmount from the document and then if you need to render the component again based on some kind of condition or for whatever reason then it will basically Mount itself and then call the use effect hook at least once okay so what I'm going to do is I'm going to go ahead and call window. remove event listener and I want to specify the event that I want to remove that I no longer want to listen to and that's going to be the same event resize whoops right over here and here's the thing though as the second argument we need to pass in The Listener function which is resize event handler right over here this is very important because if you don't pass in this call back you're not going to actually remove this event from being listened to in the documents okay so it's very important and the other reason why I did not use an anonymous function like the other reason why I didn't do this is because you actually need a reference to the function itself so that way we know which specific event and which function that handles that event to actually entirely remove it from if you use an anonymous function there's no way that you can actually know which function is handling that event and also it's not going to actually remove the event listener from the document itself or from the window in this case so that's why we need a named function so we have reference to it okay so now what's going to happen is it's going to remove this event listener uh so let's do this let me go ahead and refresh the page so obviously right now it's still going to work um let's see what I can do uh you know what maybe what I can do is I can actually move this into a different component so let me do this just to show you an example okay so what I'm going to do is I'm going to take this whole thing I'm going to cut it I'm going to paste this inside just any component I'll use the login form as an example okay any component will work fine you don't have to use the login form component you can use any component I'm going to conditionally render the login form component based on a state variable so I'll do a toggle variable so it's going to be toggled between true and false and then I'll have a button that will allow me to update the state of toggle each time so whenever I click on the button it's going to toggle between false or true true to false so basically I'm going to call set toggle and then I'm basically just going to update the state to the opposite value cuz there's only two possible values true or false and then what I'm going to do is this whenever the button is uh true I'm sorry whenever the toggle variable whenever the value is true we're going to render login form just like this okay and the whole purpose of this is I want to show you the login form component unmounting and I will add a console log inside this cleanup function unmounting login form and then I'll also add another log removing resize events listener okay so whenever toggle is true we're going to render login form login form will render and it's going to go ahead and call this us call back one time and one time only because we have our dependency array set to empty so even if State changes inside login form this will not call the call back again unless if we added that state variable to this dependency rate that's how it works so now let's go ahead and test this whole thing out we're going to go into my browser and in my Dev tools I'm going to go to elements and then event listeners right over here and I'm going to show you to verify the event being registered and unregistered so I'm going to refresh the Page by default right now the resize event listeners not being listened to because remember that we are only registering ing it when the login form is rendered to the document and currently we're not rendering it because toggle is set to false because we're doing a conditional render now I'm going to go ahead and click this toggle button which will update the state of toggle to true and that will cause the login form to render which will then cause this use effects call back to be invoked so let's go ahead click toggle now you can see right now if you look at the logs it does say unmounting login form and then removing resize event listener remember that we're in strict mode so your component your use effect hook it's going to be invoked twice okay so it renders the component unmounts it and then it renders it again okay so that's the reason why you only see this cleanup function being invoked one time hence why it logs these two messages one time only okay the second time it renders the component but it does not unmount so the cleanup function is not called remember the cleanup function is only called when the component unmounts from the document okay so I clicked on the toggle button and I can see the login form now I'm going to go over here to event listeners and I'm going to click this reload button or refresh event listeners because we did in fact add an event listener but it's just that this thing needs to be refreshed to see it so you can see now right over here I can clearly see that this resize event appears and it's on the window and you can see the Handler and I'm not sure if you can probably see the implementation probably not but it does tell you that this event is in fact being registered you can see resize is right over here and it's on the window itself okay that's awesome now of course to verify even more I can resize the window and you can see windowview Port resize is being logged which is what we have uh being called whenever we resize the window itself okay now what I'm going to do now is I'm going to click toggle again that will update the state of toggle to false which will then remove the login form from the document because remember we are conditionally rendering this component and since toggle is false login form will not be rendered so the component will be unmounted so Watch What Happens I'm going to click toggle now you can see that unmounting login form and removing resize event listener was logged to the console which implies that our cleanup function inside this use effect in our login form component is being called so window. remove event listener is being called as well okay and to verify if I refresh this event listener section you'll see that we no longer see the resize event appearing over here and I can further verify if I resize the browser the window you can see that the windows viewport resize is not being logged this was from previous but I'm I'm going to go and clear the console and I'm going to resize and you can see it's not being logged at all if I click toggle again refresh this I can verify the resize event was in fact registered and I can resize the viewport and I can see that that call back function is being invoked and it's calling the console log and it's logging this message to the console so I hope this makes sense because it's important to understand that whenever you register an event listener you need to know when exactly you want to unregister it and a good time to unregister it is when it's no longer needed and that really just depends on your application needs in my situation I don't need it if the login form is not rendered to the document so I'm going to unregister it by calling window. remove event listener inside the cleanup function okay now obviously you can register whatever events you want so if you want to register an event on the document you can so document. addevent listener there are a bunch of other events let's do a click click event right and let's go ahead and add a callback function let's call this handle document click so this will basically be triggered whenever we click anywhere in the document let's just do click documents okay and then now I'm going to just duplicate this part but instead it's just going to be document. remove event listener and it's just going to be click and then we're going to go Ahad and pass the same Handler that we used to register the click event on the document so handle document click and now I'm going to go ahead and refresh if I click toggle and I refresh you'll see now we have uh resize and we also have click which is on the document itself now I can click anywhere and you can see whenever I click on anywhere in the document it's going to go ahead and log click document okay if I click toggle you're going to go ahead and see that when I click again the logs do not log clicked document because the event was unregistered if I refresh you can see that click is no longer there same thing with resize so I hope that this makes sense because it's very important to understand how to properly register and unregister events from your document or really anything okay any HTML element now there is one more thing that I do want to show you and that's how to write custom hooks in react so far we've used two hooks we've used the usate hook and we've also used the use effect hook there are often times where you want to create your own custom hooks because you might have let's say for example a use effect hook that has a bunch of reusable logic that you may want to reuse in other components as well I'm going to show you how to do that right now it's actually very simple so what I like to do is I like to create a new folder and typically I call this utils and inside the utils folder I create a folder called Hooks and this is where all of my custom hooks will go so hooks have a convention whatever the name of your hook is you want to always prefix it with the use prefix so for example let's say my hook the responsibility of my hook is supposed to register an event listener on the document whenever I click on the whenever I click on anywhere in the document right so I'm going to go ahead and name my hook you use document click or you can call it use click documents okay and we're going to do do jsx we're actually it's going we can actually just do JS because inside this use effect we're not actually um returning any jsx at all or it's just all going to be just plain JavaScript so now this function is going to look like this function use document click we also want to make sure we are exporting it so I'll do that export ort function use document click and then what I'm going to do is this I'm going to go ahead and inside this function I'm going to go ahead and call the use effect hook and I'm going to go ahead and register The Click events inside this use effect hook okay so we're going to do document. add event listener click and it's basically going to look exactly like what we did inside this use effect okay so I'm going to copy this handle document click all back and I'll just I can actually just put it up top over here and then uh what I'll do is actually you know what I I'm going to put it inside the use effect and what I'll do is I'll just pass it right over here and then we also want to make sure we have our cleanup function to take care of unregistering the events so return and I'm going to go ahead and do documents. remove event listener click and then handle document click okay and so now what I can do is anywhere in my application I can use this custom used document click hook okay so the way it's going to look like is this first let me remove all of this stuff over here and let me remove this okay so what I'm going to do is I'm going to go ahead inside my login form so right underneath this use effect hook I'm going to go ahead and call use document click just like this okay and now if I go to the browser well actually you know what let me do this I'm going to write a console log use document click so let me go ahead and refresh the page so remember that our login form is being conditionally rendered so by default it's not going to go ahead and uh execute any of these hooks or any of the logic here so let's click toggle so that will cause our login form to be rendered and now you can see that use document click is being logged to the console which implies that our Hook is properly being invoked okay and also one more thing let me add an empty array over here because I only want this hook to uh register one time or I only want this hook to be called one time the Callback function and then I only want the event to be registered once okay so let's refresh click toggle now I can see that again because we're in strict mode it's going to go ahead and invoke that callback function twice because the component renders two times that's okay because we are also unmounting the component after the first render and we are properly handling the removal of the event listener okay so in the end our event is only registered once so you can see over here that uh we have use document click log twice after the first time it's unmounted so it calls uh this call back again and then you can see use document click is logged so anywhere I click it's going to go ahead and just trigger this events okay so this is an example of how you can create custom hooks you can do the same thing with literally any use hook or even if you are creating a custom hook that defines some State and have it returning those State you can also do it as well okay so this is just a very simple example of how to create a custom hook okay so I hope this part makes sense React Context in this section of our react tutorial I want to teach you about the react context API the best way to understand the context API and the purpose of it is to understand a problem that you will run into so let's say for example I have these three components that I just created from scratch very simple components okay I have a post container component and this is typically a wrapper component that contains all of the posts that you would want to display to the user to see such as social media posts as an example right it's supposed to display a list of posts but just for Simplicity I'm only rendering one instance of the post content component now post content is a child component of post container and post content has its own child components as well such as this post content buttons component in this case it only has one but it could have more than one and then the post content buttons component currently has nothing but down the road as your application grows you may render other elements or components in this component as well so if you think of it like this if you think of it in a tree hierarchy you have post container post content and then post content button and then of course we may render post container in a root component such as the app component itself so that would create a hierarchy of four layers now that's not a problem but think of it like this let's say for example down the road we may have to pass some props from post container down to post content and then allow post content to use those props to serve data to the user render it to the document whatever and then maybe those props will also need to be passed down to post content buttons as well and then maybe if post content buttons have its own child components it needs to pass those props as well so I'll show you an example where I have some props so I'll Define some state right now I'll just call this data just simple example hello world just simple string and then I need to pass data down to post content so I'll just call the prop data and then post content needs this prop and then we need to pass data down to post content buttons okay and then let me go ahead and take that data in and I'll finally render it inside this component okay we're not going to do the prop validation I'm just going to show you a simple example I'm going to go ahead and render post container in my app component so we can actually see it in the document in our website there you go you can see that this hello world text is being rendered from this post content buttons component okay and of course if I remove this it disappears so if you notice right now I have to pass this state variable as a prop down to post content and then I have to pass from post content down to post content buttons okay so I have to pass the prop two times now it could be more complicated I may have let's say 10 other child components that are in its own layer in the hierarchy so for example post content buttons may have other child components it needs to render and then we need to pass data down to those child components okay and we don't know how many times we have to pass that prop down until we can finally actually display to the document or do something with it and this becomes a problem when you have a very large code base when you have a bunch of different components because it becomes very unproductive having to go through a bunch of different files and just drilling the prop down each layer over and over again this is known as prop Drilling and then if something changes in your application let's say you no longer need the prop anymore well you're going to have to go through each component and remove that prop from the function signature over here from the arguments section right and you're going to have to remove it right over here and then it's just a bunch of unnecessary work that you have to worry about especially if you have a very large Cod imagine you have to pass your prop 10 times and then if you no longer need that prop down the road you're going to have to go through 10 different files just to remove that prop and then make a PLL request and then deploy that change to production becomes a headache so this is where the react context API allows you to avoid this problem so think of the react context like this instead of having my data right over here inside post container and then having it passed down to post content and then passed from post content to its child components what I can do is I can actually have my data my state set inside the context itself and I want you to think of like this the cont context itself is literally just an object okay and it's separate from the component level itself the context can hold information that can be accessible from any component that is within the context okay and again it's hard to kind of like understand how that works just from a verbal example and that's why I'm going to show you in code how this is structured okay but basically the context itself allows you to store information and then as long as your components are within the context if they're wrapped inside the context known as a context provider those components can access that data anywhere they want without needing to have it passed as a prop okay so for example post content buttons I am in the third hierarchy or in the third layer of the hierarchy or actually it's the fourth layer assuming that we're starting from the app component instead of just having our data passed down all the way to this component as a prop I can easily just reference the context and grab that data from the context okay and again the context is literally just an object that contains information that you can reference from within anywhere you want as long as you're inside that context okay so now let's go ahead and actually set up a context in react so you better understand how this works and so that you can create more scalable code bases for your react project so Creating a Context what we're going to do is this I'm going to go ahead and inside my utils folder I'm going to create a new folder called contexts you may have as many contexts as you want because different contexts can represent different things so I'm going to go ahead and create a new file and I'm going to go ahead and call this user context because this context is going to pertain to user data and I'm going to name the file with a JS extension because we're not dealing with any jsx at all okay so the way that we're going to create our context is first we need to import the create context function from react this is a function that allows you to literally create a context so what I'm going to do is I'm going to declare a variable and I'm going to call it user context capital u okay equals create context just like this and then all you do now is as an argument to the create context function you just pass in any default value this can be a string this can be a number Boolean object array anything you want okay now you don't actually have to pass in any specific value because these values are going to get overridden when you actually set the values when we use what is called a contact provider but all you need to do is just shape your data over here so since I'm dealing with with the user what I'll do uh is this I'll go ahead and just have the ID be uh I guess actually I'll set it to zero since I want my ID to be numeric value username I'll let that be an empty string email empty string and then display name empty string this can be anything you want okay it doesn't really matter what you have set over here now I'm going to also want to make sure I am exporting this user Contex variable as a named export because I will need to reference this context later on and we're done with this file so now what I can do is I can go into my app.jsx file okay and I can import the user context from the utils context user context file and then what I want to do is I want to use the user context provider okay so one thing that I should also mention is that the user context itself is an object and you have these three values you have the consumer provider and the display name we want to use the provider itself because we want to use the provider to wrap all of our components that we are providing data for that's literally why they call it a provider okay so the way that we're going to do that is like this so remember that our app compon component is our root component okay so every single component will eventually be part of app okay well I mean it actually is going to be part of app so what I'm going to do is I'm going to just copy this div and just remove it I'm going to cut it and I'm going to reference user Using Context Provider context with angle brackets like it's an actual component or HTML element and I'm going to reference provider and then you're going to it's kind of like you're rendering it okay but in reality you're actually just using the provider this is how you use it okay and then you're going to paste your component or your jsx elements whatever it is inside the provider itself okay so now what this does is inside my provider I have my post container component so any component that is within this provider or any component that is now inside the post container child components of it are now part of the user context that's what that means okay so we are wrapping the user context provider within this whole section over here which means that any data that we have set on the user context will be accessible in any component from within so the post container component can access the data of user context so it can access the ID username email or display name and then child components of post container such as post content as well as post content button because remember post content button is a child of post content which is also a child of post container okay so all of those components are within the context so they can access that data without needing to have it pass as a prop and you'll see that in just a second so before I do anything else I'm Consuming Context going to show you how we can actually access data so I'm going to go into post container and I'm going to go ahead and use a hook called use context I'm going to call this use context hook and now you can see that it expects an argument a context argument and that is going to be this user context object right over here that was created when we called create context that's why we needed to export it because we need to reuse it so I'm going to go ahead and pass in user context as an argument and this is known as consuming the context okay when you call the use context hook and pass in the context you want to consume it returns an object with the data that you had set well actually it would return the data that you set as a default value itself over here so since this is an object right over here when I reference it I can reference all the fields but if I set this to be a literal value like a number number then the return value of this would be a number as you can see over here the return value is a number and I can no longer reference those fields okay these methods are the methods on the number itself so hopefully that part makes sense so what I can do now is I can assign this return value to a variable so I'll just call this user context data just to be verbose and what I can do in this post container component is I can reference all of the fields on this user context data object and I can render it I can send it to an API server I can do whatever I want with it now right now if I try to reference these fields and try to render it it actually won't do anything and the reason why is because I'll even show you right now you'll see that if I actually go to the document and if I show you the dev tools you'll see that right now we're getting this issue that says not read properties of undefined so right over here even though we do have this default value set when we pass the object into the create context call it doesn't actually set the data for you because we need to actually set it at the provider layer over here okay so that's the reason why we're getting this error right over here when I try to reference display name as you can see it's giving us this error over here when I try to reference it okay what we need to do is we need to go back to our app component and then where we are invoking this provider there is this prop that I can pass called the value and this is going to allow you to pass data that pertains to what you have shaped in your create context over here okay so what I can do is I can set the ID so I'll set it to one I can set the username whatever key value pairs you set in this object is going to show up in intellisense over here okay so username I'll just do an the dev email anev gmail.com and then uh display name Anon the developer developer now if I go back over here let's go ahead and try to reference user context data do display name and I'll render it to the document you'll now see that the display name that I had set right over here in the value object okay that is now being displayed in the document so let's kind of just recap what is going on okay so what I did just now was I passed in my object that is based on my user context default value right over here so I passed in an ID username email display name as fields in this object and when I consume the user context all of that information is stored into this user context data itself I can even consol log this whole object to show you what it looks like and you'll see that all of the values that I set are over here and those values are coming from this object literal right over here that I passed in when I invoke the provider okay so I can go to any component as long as it's within this provider's context and consume the context itself and reference the data so what I can do now is let's go into post content and let's do the same thing so what I'll do is I will declare a variable called user context data and then I'll call use context and then pass user context so we're consuming the user context And all I'll just do is I'll just render the how about I'll render the email this time in post content so now you can see that the email address is being rendered right up top over here okay it's being rendered over here and now I'll go into my post content buttons component and I'll do the same exact thing thing I will go ahead and declare variable user context data and then call the user or call use context and pass in user context and then what I'll do I'll remove this data prop because we no longer need it anymore and this time how about I'll render the ID and now you'll see that the ID is being rendered to the document okay so you see how anywhere in my components in my component hierarchy I can access the data that is from the context so I don't need to actually pass this information as a prop anymore because I can store it in the context and then I can access it from anywhere I want as long as we are within the context okay hopefully that makes sense now I want to show you this one thing let's say for example uh let me remove post content buttons from post content so we're not going to render this component inside post content going going to remove that for now and then what I'm going to do is this I am going to go into my app component and why don't I do this why don't I uh cut this and use a fragment so I can render this and then I'm going to go ahead and render the post content buttons component like this so I'm rendering these two within a fragment okay and in post content buttons we're trying to consume the context and reference the ID now let's see what happens because notice how now the post content buttons is no longer inside the user context provider it's outside of it so we shouldn't be able to actually access this data over here let's see what happens so if I look at the document Let me refresh if I look at the document right now so you can see that we have our post container being rendered is currently rendering the display name right over here and then the post content is rendering the email which is right over here and then right underneath we have our post content buttons which is rendering the ID right over here and notice how the ID is zero and that data is actually coming from this default value right over here so even though we can actually still access the default value we don't actually get the the updated data that we set in the provider itself so while we can access the quote unquote the default value the information that we are passing to the provider as a value so the ID username email display name is what is important okay where we can we cannot access that actual data because we are outside of the context itself okay now you're probably wondering well why is this important because it may not seem like it's a big deal right now but keep in mind that we are currently passing an object literal to our provider's value but what I'm going to show you in the next example is how we can actually create a state variable and then I'm going to pass that state variable as the value to my provider that state variable is going to be an object that represents all these key value Pairs and then I'm going to show you how we can actually make updates to the data that is in the context itself because obviously over time we may want to make updates to our data that is stored in the context cuz that's just normal for any application okay and then you're going to see how that when I make changes to the data I want that information to be reflected anywhere else within the provider within the context that is consuming that data so that way the latest information is being displayed so this is kind of like a preview right now because you can see that although I am outside of the context and even though I can still access the default value even if I make updates to the context right now because this component is outside of the context it will not be able to access the latest value hopefully this makes sense now what I'm going to do now Using State with Context is I'm going to go back to my app component and instead of just passing this object literal this hardcoded object right over here we're going to go ahead and Define some states so I'm going to go ahead and call this user data set user data because right now we don't have any actual way to update the content text Data this is all hardcoded we want to be able to update the data for the context itself so typically in a realistic application what you would do is in the component that you are actually invoking the context provider you actually Define your state variable that pertains to the context data itself so since my user context is an object that represents the user itself it has the ID username email and display name I want to create a state object that represents that as well because now I have the state object as well as the dispatch function and we're going to actually use this that dispatch function to update the state itself so we're going to need to pass that dispatch function uh into the context so that way those components can access that function you'll you'll see what I mean in just a second so watch this I'm going to go ahead and for now I'm going to set all of these fields so ID username email and display name in this initial State object over here okay and again it's going to look like it's hardcoded which it is but typically in a realistic scenario you actually fetch this data from an API and then you call your dispatch function to update the user data and then that data would be actually passed into the provider's value and then your other components consuming the context would have access to it I'll actually show you another example where we fetch an API to get the data and you'll see how that works so that way you have a bunch of different examples to work with so don't worry so what I'm going to do is I'm going to pass user data right over here okay and let's just verify that everything else is still the same so you can see that we still have our email our display name and then our our buttons component over here is still displaying the default value of zero I will go ahead and remove this and go back to post content and render post content buttons okay whoops here we go and just to confirm if I go into this initial State object if I change any of these values it's going to go ahead and reflect in those components we're not rendering the username yet okay there we go right over here okay so what I'm going to do now is I'm going to go back to my user context and I need to modify this because right now our context only has key value pairs that are all literal values we don't have a key value pair that pertains to our dispatch function we need to basically set a value that represents our dispatch function so that way when we consume the context we can reference that dispatch function and invoke it to make updates to our state so you can call it whatever you want I'm going to go ahead and just call this uh set user data the same thing that is named after this dispatch function over here inside my create context object right over here and the value of this is just going to be this function over here that does nothing and since we're using JavaScript you don't have to worry about passing specific arguments and type annotating anything if you are using typescript you may have to do that but I assume you're not using typescript obviously because you're following along with this tutorial in JavaScript but I do want to mention that in case in the future you do choose to use typescript to keep that in mind so so set user data is going to be a function that returns void that's fine and remember that the the data that you set in this object doesn't matter because it's going to be overridden when you pass it as a value to the provider keep that in mind okay so what I'm going to do now is I'm actually going to go ahead and use the spreader operator to just pass in user data like this so it's essentially creating a copy of user data but then this will allow me to actually set the set user data property and pass in the dispatch function into this value over here okay so I could do it like this but since the name of the field is the same name as the uh dispatch function name itself I can actually just do it like this so now anywhere my components you can see that right over here if I reference the user context data I actually can reference this set user data property and although it is showing up as an actual field and a of function I can actually still invoke this just to keep just keep that in mind okay so when me show you right now if I go to the console you'll see right over here that in the user context object I have set user data and the data type is a function okay function that returns void to be more specific so what I can do now is anywhere in my component that is inside the user context I can invoke that set user data function to make an update to the user data State okay so watch this I'm going to go into post content buttons and I'll just go ahead and simply add a simple button again this is just just to show you a simple example okay nothing fancy so what I'm going to do is I'm going to add a click event listener and when we click on this button what I want to do is I want to call user context data or I'm sorry I want to call the set user data function that is on the user context data object and I can actually just destructure set user data from this whole object like this and what I can do let me also destructure the idea as Updating Values in Context well and what I can do is I can call set user data like a regular function because it is a function and I can update the state so whatever it is that I want to update I can update literally anything I want that pertains to my user data State itself so I can update the ID the username email display name whatever it is okay so just to show you an example I'll just update the display name so what I'll do is I'm going to go ahead and pass in that callback function because remember this is our dispatch function so it is going to allow us to take in our our callback function and that argument in that callback function gives me access to the current state and then I want to basically create a copy of the current state and then only set the display name to my new value so I'll just set this to uh I'll just literally name it updated display name okay and then now let's just see where are we rendering display name we are rendering it in post container so this is what I'm going to do uh let me do this let me kind of label everything so I know what is what let me just do that real quick okay so this is post container and then I'm going to do this post content and then let me go inside here and then let me label this as post content buttons just so that way we know what component is what so so that way we we're not just seeing a bunch of data not knowing where it's located okay so what I'm going to do now is I'm going to refresh the page and now you can see right over here we have post container and post container renders the display name so I'm inside the post content buttons right over here remember this click me button is inside the post content buttons okay we just implemented this button and then the the unclick logic over here when I click on this button it's going to go ahead and update the state of user data so that's going to basically update this state right over here and this state is at our app level which is in the same level where we are using our context provider okay so we're basically updating this user data the display name is going to be updated when it is updated keep in mind that we're still updating state so our app component is going to actually render and when it rerenders it's going to pass in the new values to the user context provider so the new value will be whatever it is that I set to display name because that's what I'm updating okay so watch what happens when I click on the click me button did you see what happened when I clicked on that button the display name was updated okay it went from an and the developer to updated display name of course this can be whatever you want you can even add in an input field to type whatever you want so I really hope this makes sense and this shows you how literally anywhere in your application you can modify your data that is in the context the single source of truth and you never have to really worry about what component has ownership of what state or what props all we need to know is that we have our data stored in one single place and then as long as we're inside our cont context we can access that data and then as long as we give an appropriate function to update that data we can do that from wherever we want inside our context Custom Data Fetching Hook okay so as I promised I wanted to show you an example where we can fetch data from an API set that data at the state level and then have it passed down to our provider for our context so let's see here's what I'm going to do I'm going to go ahead and use the same Json placeholder API server that I was using in previous examples and let's do this uh do they have an endpoint to get just one user maybe not so I think what I'll do is I'll just fetch this data and I'll just hardcode it to use the first element in this users array that should be fine for a very basic example I think actually if I do user SL1 Yep this would give me the individual user itself there we go okay so let's do that instead so again we're kind of combining all of the previous previous uh things that we've learned with data fetching and updating State all together in one single example okay and again this is a realistic example as well because in a realistic application you'll find yourself of doing things like this okay so here's what we're going to do and I'll make this very interesting so we need to fetch the data from this API endpoint and we want to perform this side effect inside our use effect hook so you might be tempted to First implement this use effect hook right over here but how about I do this instead let's go ahead and write a custom use effect hook that calls this user's endpoint to get the user self so let's go into our fix folder and let's create a new file and I'll call this use uh fetch user okay. JS and then we'll export this function and we'll call it use fetch user okay and this function is going to take in one argument we're going to make this a dynamic hook because remember how we can pass in any ID of the user and get a different user so if I pass in two or three I get a different user every single time so let's go back to our code so we'll just call this argument ID or let me do user ID just to be more specific okay so in our custom hook remember that our Hook is literally just a function and in this hook itself we can actually use other hooks so for example I can use the use effect hook and if you missed this example where I showed you how to create this custom use document click hook you'll recall that we did in fact call the use effect hook inside our custom hook okay so we're going to use the use effect hook and then what I'm going to do is I'm going to make an API call so we're going to use the fetch API and we're going to go ahead and get this URL right over here and let me go ahead and do this let me set the URL to this okay because I want to make this a little bit more Dynamic so we're going to use a template string to reference user API URL and then we're going to have to add that forward slash and then we're going to use a template string uh within the same template string we're going to uh evaluate the user ID variable okay so this whole thing pretty much evaluates this user API URL it adds the forward slash and then it adds the user ID right over here so this kind of like builds out the entire API URL endpoint without having to hardcode it okay so we're going to fetch this URL and since this is a get request it we don't have to pass in any additional arguments any additional options it just defaults to a get request we don't need to passing any headers or or nothing so we can leave it like this but what we want to do now is is we want to handle the API call because remember fetch returns a promise so what I want to do is this I want to go ahead and use then I'm going to get the response and remember we're going to have to call response. Json to get the actual user data okay so this itself returns a promise and what I can do is I can just return uh this response. Json call inside this dens callback function okay and what that allows me to do is that allows me to handle that Promise by calling then again and then this time this callback function inside this second. then gives me the actual data itself okay I'll console log it very quickly just to show you what it looks like and when there's an error we'll go ahead and just catch the error and then I'll log it just tempor arily but there's another thing that I want to show you what I want to do okay so let's go ahead and also add a dependency array and for the dependency array I'm going to go ahead and add the user ID as the dependency now I know that the user ID is not going to change at least in our implementation we won't have it change because we're going to have it hardcoded but just do know that if your user ID does change this use effect call back will run again okay this is something that we discussed in the section when we covered the use effect hook okay we're going to we're going to add some more stuff to this callback but I just want to show you how this works okay so what I'm going to do is this I'm going to go ahead and just make sure that this API call succeeds so we're not doing a bunch of things all at once and then if something wrong happens it's just going to be a nightmare to debug so we're going to to take everything step by step so let's first go ahead and call use fetch user so use fetch user and we're just going to pass in our ID so just pass in one and now we if we go back to our application let's refresh the page let's go to the network Tab and confirm you can see right over here that the API call is happening okay it is fetching the user with the idea of one and you can see that this is the data that we get back from the server okay if I were to replace one with two it would now fetch the user with the IDE of two okay so our API call is working 100% in our hook but we're not quite done with this custom hook just yet because we need to actually get the data from this API I call in order for us to actually set the data at our state level over here and then have that data passed into the context provider so what I'm going to do is this remember that inside our custom hook we can call other hooks okay and I can also call the UST State hook so I'm going to go ahead and call the UST State hook and I'm just going to set the initial value to an empty object and then for the state variable I'll just call this user data set user data okay and then basically what I want to do is when my API call is successful and when the response. Json call is successful which it should be in this case then inside this second callback function for the then call so inside over here we're going to go ahead and update the state of user data by calling set user data and then passing in data like this okay now like I said before as a beginner in react this is the common approach on how you would fetch data from an API and then update your state variable when you become more intermediate and when you use a data fetching library with a library such as react query you never have to really worry about this but it is also important to understand how to properly fetch data and update State accordingly okay so this is what we want to do so we're going to call set user data and then update the state of user data right over here okay it's pretty much it and I'm going to go ahead and just remove all of this to just tight it up a little bit so now what I'm going to do is this in my custom hook remember that your hook is literally just something that can perform other side effects it can also return data as well okay so what I can do is I can return my user data so I can return user data just like this and then if you actually go to your app component where you're calling use fetch user you'll see that uh if I assign data let me let me just call this user for now if I assign this to user and if I console log user you'll see that if I go to the console you'll see that online 10 that it is logging the user that was fetched from the API so that user that we fetched from the API we took that user object and then we set it to the user data State variable and then we returned it and then that is assigned to this user variable and when we logged it this is the result right over here in the console okay so hopefully that makes sense now I'm going to go ahead and add some more things to this hook because we might as well do that because I Tau you about that in the previous couple of sections just to make this a little bit more uh efficient so what I'm going to do is I'm also going to add the abort controller and this was something that I showed you when we first talked about Network requests so we're going to create an instance of aort controller and then all I'm going to to do is as a second argument to the fetch call I'm going to pass in this signal property and set it to controller. signal and then we're going to add the cleanup function for this use effect hook and then we're going to go ahead and just simply call controller. abort so this will ensure that if we no longer need to make the API request we actually cancel it okay um and then there's one more thing that I did also want to do as well that I didn't show you in the previous example I'm going to go ahead and add another state variable and I'm going to call this loading set loading equals use State and this will be a Boolean value and this state variable is going to track the status of the API call so whether the API is still fetching or if it has successfully returned or if it failed okay okay so basically this state variable represents if we are still waiting for a response from the server so what I can do is the moment that the moment that this call back is invoked it's going to go ahead and call this fetch function right so I can go ahead and call set loading to true and then once I am done with my API call I can set loading to false so I the best thing that I can do is I can actually call finally remember that there's a finally uh method as well and this will be called After the Promise is pretty much done whether it failed or if it succeeded so I can just do this finally whoops finally and then I'll just do set loading to false okay so even if we go into the catch Block in the event of an error it's going to still call finally okay so the loading the load variable it transitions from false to true to false during the life cycle of the API call okay hopefully that makes sense and I can also do the same thing inside this cleanup function just to be safe is set loading to false because we're no longer actually making the API call anymore so the loading variable should be false okay uh and then also I can return uh loading from this use fetch user hook as well so this will require me to actually return an object with all of the data so I'll just do return user user data and then loading like this and another thing that I can do is I can also uh track the error object as well whoops so I'm going to go ahead and create a state variable for error use States and we'll just do we'll just leave it as undefined and then what I'll do is if there is an error I'll just call set error inside the catch block and I'll just set the error object right over here now again keep in mind that um if the fetch API returns a 404 it's not going to actually error out but if there is a issue with the API call such as returning a 500 as an example or 401 then it will error out okay so let's go ahead set the error object here and I think that should be it and then we'll also return the error object as well now some of you may not know this but all of the stuff that I'm doing right over here is actually kind of like how a lot of these data fetching libraries work underneath the hood so for example react query gives you the data the loading status as well as the error object and a bunch of other different things that allow you to enhance your data fetching okay this is just kind of like a surface level example of how you can create an efficient way to fetch data okay so we are fetching the data if we need to cancel it we cancel it we track the state of loading and then we also track the error object if there is an error okay so now what I'm going to do is I'm going to go back to my app component and I know we kind of went a little bit too far with this example but again I want to show you a bunch of different things when it comes to um this example because I don't want to leave anything out okay so what I'm going to do is I'm going to go ahead and destructure the user loading an error and then I want to actually cons log all of this stuff right over here so watch this user loading error okay and if I refresh the page you're going to go ahead and see that right over [Music] here okay uh right over here on line 10 we are logging the user right over here we're logging false for loading because we're no longer loading anymore we're not we're no longer in that status and then we're also logging error which it seems like there is an error in this situation it says the user aborted a request I think that has to do with the fact that it is rendering twice so that may be why that is yeah that may like that may likely be the reason why because uh when we aborted the request it set the error but we no longer actually cleared the error so let me actually do that real quick let me actually clear the error upon success because we actually should not have any errors at all so errors should actually be undefined okay there we go okay so right over here you can see that we have the user object we have the loading status false and then we have undefined for the error okay when it first tried to make the API call yes that's fine that there is an error because the request was aborted and remember that happens because we are trying to perform two renders because we're in strict mode so the first time the component unmounts which will abort the request but the second time it renders it doesn't unmount from the document so it doesn't abort the request okay so now what I do is I can actually use the loading status to my advantage to keep track of if the API call is still happening or not okay so for example let me go ahead and console log loading and let me go into the other components and remove any other console logs because we have a lot of stuff being displayed in the console and it's starting to look a little bit confusing so let me just make sure I don't have any other console logs okay so if you look right over here we're logging the loading status on line 17 in the app component so if you pay attention you can see it says false true and then false and then false okay so initially the status of loading is false when we make the actual API call which happens when this use effect call back is being invoked we update the status of loading to true so that's why it trans it transitioned to true and then finally when we're done with the API call we set loading to false okay so why this is important is because we want to make sure that once we have successfully finished the API call and we actually don't have any errors and users actually defined with data we want to set this user data State variable right over here okay and I know that this may be a lot to takeen all at once but the reason why I'm showing you this is because this is a realistic example of how you would fetch data in a real application and then update the state and have it apply in your in your platform in your app okay so that's the reason why I'm showing you all of this so here's what I'm going to do I want to make sure that whenever the loading status is false so we're no longer fetching Whenever there is no error and then whenever user is actually defined then only I want to update user data so first let me go ahead and set this to be an empty object and then we might get a bunch of errors or yeah we might get some warnings I guess not but our document is still working fine and then what I'm going to do is I'm going to have a use effect hook right over here so for the use effect hook inside the use effect hook I want check to make sure that we're not loading there is no error and the user is defined which means that the user actually has data itself it's not an empty object or undefined because remember an empty object itself is also a falsy value okay so if all of this is true then I'm going to go ahead and call set user data and then set it to user now we will need to have a dependency array because at any point all of these values could possibly change okay and when it changes we do want to make sure that we run this call back again otherwise we're not going to get the accurate data for our state so if loading changes we want to make sure that we tell react okay hey the state of loading changed call this call back function again error may have been updated at some point invoke this call back again and then same thing with user okay and because we have this condition as long as this condition is true then only we're going to update the state of user data so now putting everything all together if I refresh the page you can see now we have the ID of two and then we have this email address that came from the API but you know let me double check to make sure that I have the correct information I mean I think the data that I had set over in some way so for example we have ID we have uh instead of display name it should be name you know what why don't I change it to name instead uh let me change it to name uh let's see I think this should be [Music] okay we have a name and then okay all right perfect so we have name email and username both overlap uh let's see is there any other data I guess yeah we have all four properties okay let me go into post container and I'll just render everything over here so we have Name ID email and then let's do username okay now watch this if I refresh the page you can see that we have the name the ID the email address email address and then I guess their uh their name itself or what is this their username yep their username and yeah this is all redundant stuff that was rendered from other components okay and to show you even another example that you could do if your data is still loading what you could do is this and typically this is actually something that you would do using react react suspense but we haven't got to that part yet so I'll I'll just show you one thing that we could do if the load if we're in the loading status you could actually return a string that says loading and then if loading is no longer true then you you can just return the post container so for example if I refresh you see that if I if I refresh really fast I don't know if you can see this but I you can actually see it over here there is this loading text that is being displayed over there but it is hard to notice um but uh that would actually require us to have the API delay and be slow but um what I could do is I could actually just go into use fetch user and I can actually just do a set time out just kind of like simulate the API call giving us a delay just just just as an example right and I'm showing you this because when you build your application you'll have all of these things noted down so that way you'll know how to you know display a custom loading text or a spinner just to indicate the status of the API call I refresh now you see it says loading and then notice how the moment when loading goes from false to True 2 seconds later it renders the post container component okay so hopefully this makes sense so I hope this example although it was lengthy it was worth following through because you learned a lot with you know how to create a custom hook to fetch data how to properly set the state how to properly check you know to make sure we're currently still fetching the data and then making sure there's no error and then making sure that our data actually is defined and then I hope in general that you understand react context a lot better because it is a very helpful tool that if used properly it is very powerful and it makes your whole application a lot more easier to manage okay so hopefully this all made Intro to React Router sense in this section of our react tutorial I'm going to go ahead and cover the basics of react router now in case if you may not know what react router is it's basically a library that allows you to set up routing and navigation for your appli application which is a very important thing in modern applications for example if you want to have different pages displaying different content such as a dashboard page a user settings page uh maybe a logout page a guest page things like that you need some kind of routing mechanism and react router does the trick it's been around for a very long time I think probably since the early stages of react so it's a wellestablished library I'm only going to cover some basic surface level stuff with react router there are a lot of topics and a lot of examples to go over and I think it would be too much to fit into this whole react tutorial so I'm only going to cover just the basics on how to get you started I would recommend after watching the section going to the react router website react router.com and just clicking on their documentation looking at some examples and reading up on how to do X Y and Z would definitely go a long way so to get started we need to install the react router package so in case if you haven't already known react doesn't come with anything except for the two core apis which is the react package itself and react Dom so we need to install react router it's a third-party dependency so we're going to go into our terminal in my directory I'm going to go ahead and type npmi and then the package is called react hyphen router hyphen Dom just like this I'll have it up on the screen for for you react hyphen router hyphen Dom you're going to hit enter and there we go we have it installed that was pretty quick and then we can verify that it was installed in our dependency section over here we are on version six as you can see right over here now that we have react RAR Dom createBrowserRouter installed we want to import a couple of functions from the package itself now keep in mind that so far in our application we only have just one page everything that we were working with was just our app component and everything was on the base URL but this time we're going to have different pages mapped by its different routes okay so we want to make sure that we actually go to our entry point of our application which is going to be the main. jsx file where we have this reactdom doc create root method being called and then we have our root app component being rendered okay and what we want to do this time is first let's go ahead and import the necessary packages or the necessary functions that we need from the package so import from and then the packag is react router Dom right over here and then we want to import create browser router and then router provider now when you go on the react router documentation there are a bunch of different ways that you can set up routing but this is the recommended approach that the document a suggest you to do so what we're going to do is we're going to remove this app being rendered right over here and instead we're going to set up our router provider it's going to look like we're rendering the router provider but we're basically going to use this router provider to set up all of our routes okay so there's actually this prop called router that we need to pass in and the value that we're going to pass in will be an instance of create browser router so what we're going to do is right up top over here we're going to declare a variable called router and then we're going to call create browser router just like this and you can see that the argument that it expects is an array of Route objects so let's go ahead and just pass an array just like that and what we're going to do is we're going to set up our routes inside this array so if you want let's say five routes you're going to end up needing to add an individual object for each route assuming that they're all just root routes so not nested routes okay I'll explain a little bit more in just a second so for example we're going to go Setting up Routes ahead and set up an object and we're going to have the Path property sets Okay this is going to be the actual location the actual path that we want to visit in our web application so we're going to set this to the base URL just a forward slash okay and then what I'm going to do is I'm going to set the element property and this is going to literally be either the HTML element or your actual component that you want to render so for my situation I want to have the app component being displayed for I guess the base route just as an example so I'll do that real quick now I'm going to go ahead and take the router instance I'm going to pass it right over here so router equals and then router and now let's go back to our web page and you can see that we have pretty much the same thing doesn't really look like anything has changed and that's fine we'll set up a couple of more routes so what I'll do is this I'm going to go ahead and set another route we'll do path and let's do slash users okay for the element I'll go ahead and just directly have a simple div because remember a div is also a component I mean it's also valid jsx I mean really the component at the end day is just going to boil down to jsx with any state or props that are being used and other logic that needs to occur so I'm just going to have this div set up over here and I'll just simply go ahead and say users and now watch what happens when I go into my address bar and if I go to to Local Host Port 5173 so my current URL but I go to the users path you'll see now we get back this div if I open up the browser tools if I go to elements you'll see that we have we still have everything inside the root div nothing's changed with that but when I go to the users path I get this div and then I get this other div and then I get the user's text okay so you can start to imagine okay well if I wanted to set up individual Pages then what I could do is I could create a custom component let's call it the users page and then have it mapped right over here and I'll show you how to do that right now so typically what I like to do is I like to create a separate folder in my source folder called pages and I like to create a new file and I will go ahead and call this file users page. jsx okay and then we're going to go ahead and create our component because a page is still technically a component I mean it is a component okay it's just we're just naming it a page that's really it you can think of it like a root component that's going to hold all the content in that page itself okay and then I'll go and return a div and then I'll just go ahead and have an H1 welcome to users dashboard okay and then we'll go ahead and go back to our main. jsx file and I'm going to go ahead remove this div and instead I'm going to render the users page just like this and then we're going to have that imported up top over here and now watch what happens when I go back to the browser you'll see that the users page component is being rendered to the document and we have our H1 tag right over here with a text welcome to users dashboard okay hopefully this makes sense and again you can have as many pages as you want so I can create another page let's call this blog posts page so this page could be responsible for rendering blog posts made by other users I'll just call this blog post page and then we'll just change this to blog post page just like that and let's go ahead and copy this paste it right over here let's change the path to blog posts and for the element we're going to go ahead and just render the blog posts page though it doesn't want to Auto Import that's fine I'll go ahead and just import it myself there we go okay now let's go back to our address bar let's change the path to /blog posts and now we are on the blog post page okay so I hope that this makes sense it's pretty straightforward stuff you're you're basically just setting up a path with a different root component is really what's going on now another thing that you can do with react router is having Nested/Child Routes nested routes these are also known as child routes as well child routes of the root route okay so far these routes over here that we have set up are their own individual root routes and each one of them actually has this children property and you can use this to set up child routes or nested routes okay so for example I'm going to go ahead and remove this users route right over here and I'm going to actually set up the users's route as a child route inside this uh base path right over here so this base route will have child routes and it's going to look very similar to how we've already been setting up our routes so we're going to have an object okay because you can see that if I hover over this the data type is route an array of Route object object which is very it's pretty much the same thing as what you pass in over here route object okay so I'm going to go ahead and set the path to uh users and then the element will be users page just like this so let's go ahead and try to go to slash users right now so I'm going to go ahead and change the address to SL users and now you're going to notice that right now the users page actually does not display at all it's displaying let me zoom out a little bit it's displaying the contents of this app component which is all of this stuff over here so one thing that you must know is that when you have child routes this app component over here becomes the parent route so it's actually going to render the parent element and then it's supposed to render the child element as well well based on the path so in this case it should render app the contents of app as well as the contents of users but for some reason we're not seeing the contents of the users page component now the reason why this is happening is because we need what is called an outlet Outlet whenever we want to render child routes okay so the way that we can do this is we need to go into our parent element which is the app element and then what I'm going to do is this I'm going to go into I guess I'll just do it outside the provider for now and then I'll go ahead and just render this Outlet well let me import it first so we're going to import outlet from react router Dom uh let's see it should come from there yep import outlet from react router Dom not sure why intellisense is being weird about it but let's just render this as if it's a component well I mean it is a component and now this will basically render the child element users page so now watch what happens when I go back to my application you can see when I go to slash users I can see the root page element so this is the app component right here and I can see my users dashboard component right over here or my users page component of course if I were to go to just the base page I'm only going to see what is on the app component I'm not to see what is on the users page itself okay so you can actually use this approach to build layouts you can you can have like a global navigation bar and you can have all of your child uh paths like defined over here so for example I'll just show you a quick example real quick I'm going to go into my app component and I'll just set up a very simple navbar I'll do it outside of the context because we don't really need the context I'm going to use the nav component and I'll use an unordered list and I'll just have a very simple uh list item so we'll have let's do this let's [Music] do let's do this let's do home and then let's do users then let's do one for blog and let me also make sure I change the url so this will be user and then this will be blog posts okay um this should be fine and now let me move this into the children array right over here let me make sure the paths are correct blog post okay so right now you can see I am in the homepage the base URL if I click on users it takes me to users if I click on blogs it takes me to the blog posts page if I click on home it's going to take me back home okay now obviously since we are using uh these link tags it's looking like we're refreshing the page if you wanted to avoid that from happening you don't want to use a link tag what you would do instead is you can actually just do this you can remove the a tag over here and there should actually be a link component that comes from react router I'll show you how that works so let's go Link Component ahead and go up over here and let's import the link components whoops here import link from react router domum and what I'm going to do instead of using the the a tag for all my links we're going to use the link tag or it's a component itself okay so what I'm going to do is I'm going to go ahead and just have my home text right over here and then we want to pass this to prop and this is going to be the actual URL that we want to navigate to so the URL that we want to navigate to is just going to be the base URL for home for users it will be [Music] users and then for blogs it'll be blog posts okay and let's go back to our page let's refresh and Watch What Happens so notice how now even though it technically actually still is let me show you it still is an a tag but it doesn't do that refresh behavior that it did before when we clicked on each one you can see when I click on the actual page notice how the data is not being refetch because before we were actually fully re reloading the page okay this time I can click on home be navigated to home I can click on users it'll take me to users and you can see the address bar is updating and then I can go to blog post page just like that okay so hopefully this shows you an example of how you can have a root page right over here you have your root element app and this is pretty much Global right any child element that you go to so if I go to users page will also have the contents of the app component being displayed as you can see it's happening right over here okay so if I actually just removed all of this stuff over here this provider stuff this would look like a global navigation bar for my entire application okay so hopefully this gives you some ideas on how you can set that up now of course uh if let's say for example if you want to have individual Pages without being rendered within the actual root page itself then you don't want to have that path or you don't want to have that route set up in the children array for the root path you would want to have what we had previously where we had this users path as its own root path itself so now if I click on users you'll notice that it takes me to the users route and it renders the users page but we no longer see that Roots app element on top of it because we are in the users path right now and it doesn't have any root element that it's rendering okay but if I go back and if I click on blogs oops yep if I click on blogs you can see that the blog post page will still render the app component because it is a child route of the base path which is rendering the app component it can be a little bit tricky at first to understand but once you play around with this which I encourage you to do like try different scenarios out it'll begin to make a lot more useNavigate Hook sense now I want to show you how we can programmatically navigate users which basically just means navigating a user based on either a condition or whenever an event happens in other words we're not actually allowing the user to see like a Navar and then clicking on links like how we have it set up right now we want to make it so that let's say if they click on a button and we listen to the onclick event and then we navigate the user or if we fetch some data and if the API call is successful then we'll navigate the user something like that is what I mean when I say programmatically right because right now I see this navigation bar I can just click on these links that's not programmatically okay I want to be able to navigate the user during the life cycle of my component or when some thing happens such as when we type to an input field or if uh we receive a websocket uh data from the server things like that okay so to do this we actually need to use a hook that comes from the react router package called use navigate okay and this is a very popular hook that you're going to want to know about so I'll show you how that works so I guess a good example is let's do this uh let's do this I'm going to go ahead and go into my okay let's do this inside this use effect hook I'm going to go ahead and navigate the user to the user page once they have successfully fetched the data and updated the state so in the app component I'm going to go ahead and call this use navigate hook right over here we need to import it of course so let's import that okay we're going to call this and it's going to go ahead and return a value so let's store that in this variable and this value is actually a function specifically the navigate function and you're going to use this function to programmatically navigate your users to the route that you want them to be at so for example inside this use effect callback after we check for this condition if this is true we're going to set the state and then I'm going to go ahead and call navigate and I'm literally just going to pass in the URL I want to navigate the user to so I'll navigate them to the users page right over here the uses route and I can also pass options as well uh if I wanted to pass like some State I could but I'm not going to I'll just call navigate and since we are using this navigate function in inside this use effect callback it's complaining that we need to add this as a dependency so let's just do that as well it shouldn't really affect this logic over here so let's go ahead and see what happens so you can already see that behind the scenes or in the background it already did it for us already but let's go to the base URL and you can see now see how it like instantly navigates us to the user's dashboard now okay this is not really the best examp example so what I'll do is I'll show you another example where we can programmatically navigate users Navigating Programmatically so what I'll do is I'll set up an input field right down over here let's go ahead and do this real quick let's set up a div let's give our input field a label uh enter data and then input and let's set the ID to data I don't need any state for this because I don't really care about uh tracking the state of this input field I only care about the value of what we type in so all I need to do is just listen to the onchange event and then handle that events whenever it's triggered which is basically whenever we type or paste the value or just whenever we change the value of the input field so I can easily just reference the event object target. value property so let me just show you real quick make sure that this works of course so notice how I can type and whenever I type I can see the value of the input field being logged in the console so what I'm going to do is I'll just show you this as a very simple example if the value is let's say the length of it is greater than 10 then I'll just navigate the user to the blog post page okay again this is just a very simple dummy example nothing complicated the whole purpose is just show you how this navigate function works that's really it okay so navigate blog posts and then watch this I'm going to refresh the page so let's go ahead and type something that is greater than 10 characters so I'll type Anson the dev and notice how the moment I type that last character V makes that whole entire string greater than 10 characters and you'll see that it navigated us to the blog posts page and that's how you can see over here that over here it says welcome to blog post page because we are now in the blog post page okay so I hope that this makes sense now very quickly I'll also show Passing State to Route you an example where we can pass State uh from the navigate function cuz that was something that I did mention very briefly so for example if I pass in this object I can set this state property and I can literally just set any piece of value I want so for example I can literally just pass in something like I don't know posts and then id1 title posts or let's do Hello World content welcome to my first post okay so basically what I'm doing is when I navigate programmatically to this blog posts page I'm also going to send some state so it's basically is going to be an object that has this post property which is an array of post objects in this case now remember since this blog post path is associated with our blog posts page because we set that up in our router that means on the blog posts page what we can do is access the state that we passed when we navigated to that path programmatically okay so this blog post page we can access this post array I'll show you how to do that so in this component what we want to do is we want to use this use location hook which comes from react router as well so I'm going to import use location from react router Dom and then keep in mind that this use location hook will return a location object it's not the same location object the global one that is part of the actual browser right over here so what I'm going to do is I will go ahead and actually just name this router location instead so that way we don't get confused and I'm going to call use location and now watch what happens when I console log router location I'm going to show you what this looks like it's an object so let's go into our page again and let me go back to the base path okay so currently we're on the base path Let me refresh again so notice how now if I go to the blog post p page this is the object that is the location object from the use location return value right over here and you have basic properties hash key path name search things like that but you see how we have this state property and currently it's null but notice how now if I go back to the homepage and let me type some stuff into this input field so I'm going to type ANS in the dev so so I typed 11 characters so that navigated us programmatically to the blog posts page and you'll see the blog post page is being rendered and notice how if I expand this object now you can see that the state property is now defined and the state property has this posts property and as I mentioned earlier the state property is literally just an object and it has this post property which is what I set right over here when I did the programmatic Navigation okay so what I could do is I could reference the stat and I could get the post property you also have to keep in mind that we need to check to make sure that state is in fact defined as well as the post property is defined as well because it's not guaranteed that the state will be defined because you could actually directly just go to the blog post page yourself and that would pretty much SC skip this whole programmatic navigation right over here which means that there is no State being passed okay so you always want to make sure you check for that so what I could do is let me just destructure this state property from this uh use location call and then what I can do is this I can actually probably do something like this I can probably wrap this in the use effect hook and then what I could do is I can use the state object as my dependency and I can check to see if state is defin and if state DOT let's do posts is defined then what I could do is I can actually Define some local state for my blog post page so let's do that so this will be an array of posts so if state is defined and if the post property is defined which is an array then we'll go ahead and call set posts and we'll just pass in state. posts just like that okay and then down over here I will render posts so we'll do post. map and then we'll go ahead and just render a simple div for each post and we'll render the title and the content so what I'll do is I'll do an H2 tag render post. tile and then I'll have a section where I'll render a paragraph post. content is very simple markup let me go and make sure I use the post ID as the key for my div can't forget that and let's go ahead and see if this works so let's go back into our page now notice how now if I refresh you'll see that we actually still have the posts um right over here which implies that this state and state. poost property is defined and even though when I refresh the page we're not doing the programmatic navigation anymore now you may have also noticed that even though when I refresh the page I actually still have the state right over here I have my posts right over here even though I didn't do the programmatic navigation right because the way that we set up our code is that when we type more than 11 charact or more than 10 characters it's going to programmatically navigate us to the blog post page as well as send some state to that page that we can access but I'm refreshing the page and you can see that I still have the state so the state is still present and I still have the posts now the reason why this happens is because actually behind the scenes what's going on is that the state is actually stored in the browser's history okay there's a history API that is being used and I could probably show you right over here if I were to console log window history and then let's see there should be the state property it should be stored right over here so let's see we're on line8 so let me zoom in a little bit so you can see right over here yep right over here you can see that the state is still over here when I refresh the page no matter how many times I refresh that state is still stored in This Global window object which has this history object right over here and then we have this state object okay now if I were to actually go to the homepage so I load up the homepage and then let's say if I go directly to the blog post page you'll notice that now we no longer have that State anymore so kind of like cleared and you can see that over here there's no state in the global window. history object and then State over here is null which is from the use location hook okay so I just wanted to bring that up and in case of you are wondering like why it was the case that we still had our post even though I refreshed the page okay that's because that state was stored in memory so that it can be accessed easily okay so but if I were to go back here let's go back to home go to blog post stay is still undefined that's fine let's go back to home let's type anev now we have our state we're on the blog post page I can refresh as many times as it want it's still going to have the state and another thing that I will mention is that you'll notice that if I go to the blog post page right now let me just type some stuff so we have our state but you'll notice that if I go to the base path like this where I manage it in the address bar and I hit enter the page itself actually refreshes like the entire window refreshes right and then if I go to the blogs the blog post page I no longer have my state and that's because like if I were to navigate in the actual app and not through the address bar so let's say for example if I just type and now if I navigate in the app I still have my state because that state is still saved in the window but when I go to the address bar and if I change the address itself I change the path and if I hit enter this reloads the whole entire page so that state is going to be cleared so that's the reason why if I go to blogs right now I no longer have that State and if I were to go to blog post directly here I no longer have that state so I just wanted to mention that in case some of you might be having questions about Intro to Unit Testing with Vitest that in this section of our react tutorial I'm going to teach you how to test your components now I'm not going to give you a whole explanation on why you should test your components in react it should be pretty obvious but if it isn't I will quickly mention why you should test every single developer should learn how to test their code because when you are deploying your product to your customers you want to make sure that your application has the least amount of bugs possible notice how I said least amount of bugs and not bug free because there isn't any such application that is 100% bug free there is always going to be some type of bug that is introduced in your application whether it was because you improperly handled some kind of uh use effect or some kind of algorithm or maybe a new feature that you wrote introduced a bug into the application testing allows you to ensure that each time you write some code or if you introduce a new feature that the current state of the application does not break the behaviors of the application remain the same okay so there's a lot of things to talk about when it comes to the fundamentals of testing we're not going to dive into that I'm just going to teach you how to write unit tests for your application and then we'll dabble a little bit in some integration tests using something called a mock service worker so with that being said the tools that we're going to be using are vest which is a testing framework and we're going to be using react testing Library so normally before vit was popular when everyone was using Create react app we would use just and then we would use it with something like enzyme or react testing Library enzyme isn't really as popular anymore I don't really know if there are people still using it but react testing library is the go-to library to use to test the behavior of your react application so that's what we're going to be using so we need to install a couple dependencies and set up our project in order for our test to correctly run and it's nothing complicated so what we're going to do is we're going to go into our terminal so inside my react tutorial directory I'm going to install a couple of packages so Setting up Vitest & React Testing Library I'm going to type npmi hyphen D these are all going to be Dev dependencies because all of these relate to testing and testing is primarily for the developer experience not really for your customers to see okay so we're going to install vest and then we're going to install at testing hyphen Library forward SL react and then we're going to install jsd and then we'll hit enter now that we're done installing our dependencies we're going to go into our code repository or our project and the first thing that I'm going to do is go into Configuring vite.config.js for testing the V.C config.js file and we're going to set up this file for tests so inside this object that has passed into the defined config function that is called we're going to go ahead and set up this test property which is an object and this allows you to to configure your tests so the first thing that we're going to do is set up the environment and we're going to set that to jsd and we need to make sure we have jsdom installed which we just did okay if you don't have jsdom installed and when you try to run your tests using Vest it's going to throw an error and tell you that jsd is not installed the next thing that we're going to do is set up this property called setup files and you may recall this was something something that was done with create react app but we're not using Create react app obviously so we're going to have to set this up ourselves so we're going to basically have this setup files property ma to a file called setup test.js which we don't have currently but we are going to create so I'm going to have this setup test.js file okay that's going to be in the same directory as my config file for vit so we're pretty much done with this this so what I'll do next is I'll go ahead and create that setup tests file so in the same directory or you can create this wherever you want I'm just going to create in the same directory as my V.C config.js file I'm going to create the setup tests. JS file and now in this Create setupTests.js file setup test.js file we're going to actually need to import a couple of functions so first I'm going to import after each and this is going to come from the V test package then we're going to import this cleanup function which is going to come from the testing library for react package now there actually is another package that I did not install and we're going to install it very quickly and that is going to be the at testing hyen Library slj we need this package as well okay there we go and now what we're going to do is import at testing Library slj Dum and we want to import v test over here okay and then what we're going to do is we're going to call the after each function so this is a hook if you've used just before this is pretty much very similar pretty much after each test it's going to invoke this callback function and all we're going to do is just call the cleanup function like this okay and then we're pretty much done with this setup tests file and what we want to do next is we want to go to our package.json file and set up a test script so right over here I'm going to set up the test script and then it's going to execute the vest binary okay and you can see right over here in the dobin folder in our node modules folder we should have that vest uh package right over here okay pretty straightforward stuff hopefully that makes sense so whenever we run our npm script it's going to go ahead and execute this vest binary for us so that's going to run our tests so this is pretty much a very very easy basic setup if you need more different things to configure you can go to the vest documentation and just click on config and then there are a bunch of things that you can configure here for your application okay but this is going to be just the bare minimum that we need so now what we're going to do is create our very first test so what I'm going to do is I'm going to go into my source folder and I'll create a new folder and typically what developers do and this is industry standard is they create a folder called uncore uncore testscore underscore and the reason why for the underscore is because it actually moves the folder all the way to the top of the the folder tree so you can easily see where it is instead of having to dig through a bunch of different directories you don't have to put it inside the source folder if you prefer you can put it outside the source folder but I'm just going to keep it inside the source folder for now now I don't want to make this first example very difficult for Writing our First Test all of you because some of our components are using things such as the context API some of them are using react router and then we're using uh we have a component that is fetching data from an API and I don't want to just immediately scare all of you when it comes to testing so what I'll do is I'll just create a very easy component I'll just call this username display. jsx and then all this component is just going to do is just take in a prop a username and it's just going to render it and that's all it's going to do okay that's literally all this component is going to do very simple and I'm going to show you how to test this it's complaining about the prop valid I'm not going to worry about that right now because it's not going to affect our test at all so what I'm going to do is since my component is called username display I'm going to want to create a test file that is matching the component name because that allows me to keep track of it so I'll call this username display and then we want to use the dopc extension or test extension you can use either one and then you want to end it with jsx so if you do uh test. jsx this would work fine if you wanted to use. spc. jsx that would also work fine as well okay so now what we're going to do inside this file is first we're going to import the describe function from vest there is a way to actually set up these functions globally uh I tried looking it up on Google but I think it primarily works with typescripts I wasn't able to get it working so for now we're just going to import these functions manually from the vest package okay so I'm going to import describe and then I'm going to import it these functions may be very familiar if you've used just before or something similar so describe is a function that's going to allow us to set up a test Suite so in other words it actually allows us to group together our tests we don't actually write the testing logic inside our described function body we just use it to label our test and group them together okay so what I'm going to do is I'll just go ahead and give the describe a name inside these inside these parentheses as the argument over here so I'm going to go ah a and just call this username display just very very basic stuff for now okay and then we're going to to pass in a callback function as the second argument this is how every single describe is going to work you have the name of the test suite and then the Callback function and then inside the Callback functions body is where you actually are going to set up your tests using the it function or alternatively you could actually also use the test function as well so if you wanted to write your first test you would use the it function or the test function and it would look something like this so let's say for example uh for my name I'm going to go and say it should render username okay and then pass in the Callback function and then this is where you would write your testing logic if you wanted to use the test function instead it'd be the same exact thing okay the same exact thing same arguments it doesn't really matter which one you use at the end of the day okay so as you can see right now what I'm doing is I have my describe my test suite and I'm just giving it the name username display inside the body of the test sues callback function is where I'm going to use the it function to actually write my tests okay so what we want to do is for the first argument you always want to describe or you want to label what the test is actually going to do so in this case I'm saying okay it should render username and that's what our test should do it should that's what it should test for okay so we're going to write our testing logic inside uh this callback function's body the one that's passed through the it function and this is how we're going to do this okay with every single test in react when it comes to testing components we want to make sure that we first render the component that we want to test so in this case we're trying to test the username display component so we want to Rendering Component Under Test render that component now here's the question how do I render that component you might be wondering well do I import the component so let's import our component first and then do I just do something like username display like that well not quite so this is where react testing Library comes in so we're going to use react testing library's apis to actually render the element to the document and then we can actually use a function that comes from vest called expect to write assertions okay so what I'm going to do is I'm going to first import whoops I'm going to import this render function from the testing Library react package this is something that we installed earlier in this section of our tutorial and what this function allows you to do is just render your component or element whatever it is that you want to render into a container and then that's pretty much rendered to the document itself the body of the document okay so what I'm going to do is I'm going to call render and then we want to pass in our react node so it's basically going to be our component over here username the display but we're going to pass it as if we are rendering it like this okay so you want to make sure you pass it like this as if you were actually writing jsx instead of passing in like this okay so that's pretty much it with rendering our component and now what I'm going to do is I'm just going to show you how you would actually execute your tests so right now we have no assertions so our test actually should pass so what I'm going to do is in my terminal I'm going to go ahead and execute that test script that I implemented in the package.json file right over here so we're going to go ahead and type npm run test and that will execute the v test script and you're going to see that's going to run our username display. test. jsx file okay and let's see what happens okay there we go so you can see that nothing errored out with which is fine and nothing uh nothing bad happened of course it's going to pass we haven't written any uh we haven't wrote any assertions one thing I do want to mention is this render function actually returns an object which is an instance of render result so we can assign it to a variable and there are a bunch of different properties that we can reference you don't really need all of these but sometimes some of them may be useful so I'll show you an example where we do something called snapshot testing with the container because right now this container itself actually gives you the HTML element so for example if you hover over this the type is HTML element and there are a bunch of properties that pretty much you would see on any HTML element itself so what Snapshot Testing I'm going to do is I'm going to show you one type of testing called snapshot testing which is very common and it is not as popular and it really isn't super important but it can be very useful in many situations okay so what I'm going to do is I'm first going to need to import the expect function and this is going to allow me to write an assertion so what I'm going to do is I'm going to call the expect function and I'm going to pass result. container because I'm going to write a snapshot test on the container itself on the HTML element and then there's going to be this matcher called to match snapshot and I'm going to go ahead and just call that function right over here it's just a function on the return value of expect okay now I'm going to go and save this and let's go ahead and run the test again and I'm going to show you what happens when we create a snapshot so you're going to see in the in the console in just a second it's going to go ahead and say snapshots one written okay and you can see that on the left hand side we have this snapshots folder that was created and then inside that folder it created the this file same name as our test just ending with a snap extension let's click on this and you can see that right over here we see our test Suite username display and then we see the actual test name that was ran and you'll see that right over here we have the HTML that is displayed right over here and that is coming from the container itself so why is this important well snapshot testing is a way for you to whenever changes happen to your UI whether you made it yourself either purposely or accidentally and this is useful because sometimes you might have a UI that you don't really expect to change at all perhaps that UI is only supposed to display static content and you don't expect it to change at all okay and then let's say you have a snapshot test and then your snapshot test fails because now the UI is different so what happens is it fails and it tells you about that and then you can go back and review the test and say okay is this snapshot test failing correctly or do I just need to update my Snapshot so for example right now what this is basically doing it's it's kind of like taking a photo of your UI okay and it allows you to keep track of what it looks like if I were to go to my UI right now and let's just say for example I change this from a span to an H1 okay and then if I run the test again which automatically does this you'll see that now the test actually fails and you can see that it says expected a span but we received an H1 tag so what this snapshot is telling me is saying okay well your your snapshot test failed because the original snapshot that we took we had a span but now your UI says it's an H1 tag so you have two choices go back to your UI go back to your component and revert the changes from an H1 tag back to a span tag or update your snapshot okay there's no right or wrong answer here it's just really up to what your intentions are if your intention was to actually update the component and actually replace it from a span to an H1 then all you need to do is update your snapshot and you're basically saying hey the previous snapshot is old we no longer care about it anymore it's obsolete update the snapshot so right over here it tells you press U to update snapshot so if you press U you're going to go ahead and see now the snapshot was updated instead of it being created and if you go back to the snapshot file you'll see that now it's an H1 element instead of a span hopefully this makes sense now obviously this whole tutorial is not about snapshot testing I just want to very quickly show you how that works let's go ahead and actually write the test that we wanted to which is ensuring that the username is being rendered to the document so what I'm going to do is I'm going to go and just comment this out and I'm going to change this back to a span we no longer care about our snapshot test so I'll just comment that out for now and what I'm going to do is I'm going to go ahead and write an assertion to verify that the username is being displayed to the document now you're probably wondering well okay I need to make sure that the username is actually first of all being rendered how do we make sure we do that well here's the thing though right now we are passing the username display node to the actual render function to have it render but if you didn't notice in the snapshot test you'll notice that right over here we actually don't have any text being rendered at all it's just an empty H1 tag or it's going to be a span tag now and the reason why is because we're not passing any props to our username display component remember that your components if they have props you need to make sure you're passing them otherwise if it's being rendered which it is it's just going to be empty which is why you saw that right over here nothing was being displayed at all okay well the H1 tag was there but it was just empty so let's go ahead and pass our prop so we'll do username and then we can just literally pass anything we want I'll just pass ants in the dev and then now what I'm going to do is just very quickly I'll actually run this test again just to show you uh what this looks like and then you'll see that in the snapshot you can see we actually have our span element with the actual user R because we passed the prop into the component okay so anytime you need to test a component that expects props or needs to receive props you just pass it in regularly as you would in just plain jsx okay so what I'm going to do is this I need to verify that the username is on the screen it's in the document now the way that we're going to test our user interface is by using this Using Screen to Query Elements screen API which comes from react testing Library so we can import screen and this screen is a constant and it has a bunch of different methods that you can use to query your document to look up elements find elements search for elements things like that okay and there are a bunch of different ways that you can search for elements you can search for them based on the text you can search for the elements based on their test ID which I'll explain a little bit more later on you can search for elements based on their role such as if it's a button if it's a text text box if it's a list I'll explain a little bit more about that as well you can look up elements based on a bunch of different things label text uh display value that's for input Fields um things like that okay so I'll show you an example where we can search for our username based on the text using the screen API so what I'm going to do on this screen object is I'm going to call getByText query the get by text function or query I'm going to use those terms interchangeably okay and this get by text query takes in a couple of arguments so for example the first argument is going to be the matcher itself so here you can either pass in the actual string value that you want to search for or you can pass in a regular expression to match the string in the document so for example I know that my component is supposed to render the username an the dev so I can pass in ANS the dev like this if my text is more complicated perhaps maybe I might be concatenating my text with a bunch of other uh texts as well I could use a regular expression like this okay whatever you need to do either you need to pass a string literal or a regular expression I'm just showing you these two Alternatives okay since our text is pretty simp simple I'm just going to use a string literal so what this will do is it will make an attempt to find the element in the document if it cannot find the element based on this text an the dev what will happen is it will throw an error so get by text will actually throw an error or if it finds two elements that are associated with text with this text so if it finds let's say two span elements with the same text an in the dev it's going to throw an error and you'll see in just a second how that works so right now we only have one HTML element the span tag the span element with the username an in the dev so this test should be fine so what I'm going to do is I'm just going to copy this copy this and then I'm going to call expect and then just pass this screen. get by text call into expect okay and then what we want to do is just call the matcher to be in the document okay so basically this assertion that we're writing is we're asserting that this this uh an in the dev text is in the document okay there is an element with the text ant in the dev that is in our document okay that is what this matcher will do for us it will verify that it is in the document okay so since I don't need this result object anymore I'm going to go and just remove this part we still need to call render now let's go ahead and run our test again and let's see what happens uh you can see that it actually did pass but I'll just rerun it again just to show you uh let me actually update the uh let me do this okay so we removed the snapshot cuz we no longer need it so you can see right now my test actually passes okay okay so let me go ahead and do one more thing let's go ahead and actually just pass in a value that I know is not in the document just to make sure that we don't have any false positives which could happen occasionally so I'm going to pass an ants in the devs with an S and I look at the console and you can see our test actually fails so this verifies that my test that passed previously is actually passing correctly okay so you can see over here we get some feedback it says unable to find an element with the text an the devs with an S and it gives you some uh hints on why that could possibly be the case and then it renders the body right over here and then or the HTM element which is a body and then you can see we have our divs and then we have ANS in the dev right over here okay and then it goes ahead and points out what's the possible issue you get the point okay and I'll show you an example where where I can use a regular expression so let's just say for example I only care about matching the text Anson with a regular expression and then you can see my test actually passes if I were to do let's say if I just did something uh I don't know let's just say um H I guess developer let's try that that will fail okay but if I did Dev this would pass because Dev is part of is a substring of ants in the dev so that matches so it's going to pass okay now let me put this back to a string literal and I'm going to show you what happens when I actually render the username two times and I'm going to show you how that affects my test itself so now you can see that when I look at the console after my test reran it's going to go ahead and fail and it says found multiple elements with the text an the dev and that's just the nature of this query get by text and if you look at the documentation it'll tell you right over here uh the get by family of queries so get by text get by label text get by display value get by rooll etc etc all of those queries will fail if it finds uh more than one matching element for the query okay so it tells tells you to use get all bu so if we wanted to search for or if we wanted to write a test to assert on multiple elements we would want to use get all by text instead okay so get all by text and S the dev to be in the document and then now let's see what happens uh received value must be an HTM element or an SVG element well you know this time this actually returns an array of elements so we would have to actually modify our test just a little bit so uh what I could do is this since this is no longer an actual HTML element itself it's an array of HTML elements so I probably would have to uh iterate through let me see if there is let's see uh let me do this I'm do cons elements equals get all by text so now I have an array of HTM elements and then what I could do is I could just do elements for each elements expect elements element to be in the document there probably is a simple matcher that I can use to uh check all elements on the documents but off top of the head I'm not really sure about that maybe some of you that are experienced with react testing Library can tell me uh but yeah you can see right over here I'm using a for each method on the array of HTML elements and I'm writing assertion for each element verifying that it is in the document and our test passes if I were to negate this using the not assertion right over here or the or the not operator you're going to see that it actually fails because the element is actually in the document okay so hopefully this makes sense now before we move on I wanted to spend Understanding getBy vs queryBy queries some time to explain the difference between the get by query versus query by so for example some of you might be wondering well okay instead of using get by text why don't I just use Query by text instead and if I were to rerun the test you'll see that it passes and it works just fine so why do I use get by text when I use Query by text or the other way around so this leads to the question when should I use get by text versus query by text like what's the catch using one over the other so the important thing that you must understand is this so I'm going to show you this documentation right over here because it's a great point of reference so the get by query and the query by query they both return the matching element from the query itself so when you call query by text or get by text it's going to go ahead and return the actual element itself granted that it's found in the document itself but here's the part where you need to understand the way that these functions handle when the element is not found in the document is different so if you look at this part over here where it's describing the get by category you'll see that right over here if the element is not found in the document then it will throw an error for query by if the element is not found in the document it will not throw an error but it'll return null okay now you're wondering well what's the purpose of this Well here here's the purpose of this so let's say for example if you're trying to test for an element that does not exist and the documentation tells you right over here to use Query by to assert elements that are not present in other other words the elements don't appear in the document itself then you want to use Query by because it's not going to error out if the element was not found so you can easily write an assertion that says okay well this element is not found so I expect this element to be null okay whereas if you were to try to test for absence of an element using get by well it's going to be difficult because it's going to error out and I'll show you an example so what I'll do is I'm going to go ahead and remove uh this username right over here I'm going to remove the render of the username and I'm going to show you right over here so you you'll see that the the test actually fails right now but it's not failing because of this 2B in the document matcher it's failing because this get by text is uh is erroring out okay you'll see that it says unable to find an element with the text and it points to this part over here it's not failing because of this I could literally do something else like I could do something like to be I don't know to be checked like just let's just use some random matcher okay and when the when the test runs again you'll see that it's pointing to this part over here not this part okay so it's not the matcher it's the get by text and go further to go a step further I will just call get by text and you'll see that now our our our function still errors out okay unable to find an element with the text an in the dev because it doesn't exist okay now watch what happens when I use Query by text instead you'll notice that even though the element is not in the document it clearly isn't it doesn't error out and our test falsely passes okay so now you can see the difference between query by versus get by and this is the same for all variants of the query by or get by text so for example it's the same thing that happens if you were to use get by roll or query by roll okay so now that you understand the difference between both let's show you an example how you can handle the situation when they're not in the document okay so let's say if you're adamant on using get by text for whatever reason because you enjoy using get by text but want to test for an element that doesn't exist in the document well how would you do that well the way that you would do this is not by actually writing an assertion that the element doesn't exist in the document you would actually write an assertion on the error object itself so the way that that would look like is like this you would use a tri catch like this and then what you would do is this you would you would uh call screen get by text and then and the dev and then you basically write the assertion on the error object to be defined now obviously this this error object is always going to be fined because first of all you are setting up your test in a way for this get by text call to fail and in order for this error object to be defined you have to be inside this catch Clause anyways right so this is one way to do it the other way that you can do this is uh I'll show you let error equals we'll just do let error we'll Define a uh we'll declare a variable called error and then I'll do error equals error like this and again this is a very hacky way to do things I would not recommend doing it but there are times where you do need to write a test using TR catch not for this case because we have a query by tool to use so we're not going to obviously do it this way I'm just showing you an example okay so this is what you would do right you would pretty much just kind of like hack your way through this we know that this get by text call will fail so inside the catch block we're going to go ahead and set error to error and then right outside the catch block so we're going to write an assertion on the error object to be defined now obviously if get by text uh doesn't fail then this will be undefined so this whole test will fail okay now again I would not recommend doing it this way I'm just showing you it because if you're very adamant on doing it this way and if you have to use get by text and this is what you would do at least this is what I would do if I needed to do it but I wouldn't do it this way okay instead the correct way that we want to do this is like this so first uh here's what I'll do we're going to go ahead and call query by text and then we'll go ahead and pass in the text that we want to query for that we know is not in the document okay so then what I'm going to do is I'm going to copy this and I'm going to pass it into expect and now we know that the query by query will return null if it's not found in the document instead of erroring out so what I can do is I can say Okay expect this whole thing to be undefined like this well actually not to be undefined uh two well we wouldn't use to be undefined because null is technically not undefined like that null is actually still a value is not on theine we want it to be to B null I guess yeah 2B null is the correct one sorry about that and now you'll see that the test actually passes now there are other assertions you could use like for example there's not to be in the document and you'll see that our test passes so we're writing an assertion we're saying okay this text an the dev is not in the document because it findBy queries clearly isn't and then we can see our test passes okay now of course if I were to change this to be Tob in the document our test actually fails and you can see that the receed value must be an HTM element or an SVG element and that's complaining because this value over here is null okay so again I hope this makes sense and I hope that you better understand the difference between using get bu versus query by now there is a third type of query called find by so for example I could have also used find by text instead of query by text but you're wondering well when should I use the find by queries instead of using get by or query by in order to understand this better let's first understand what exactly F bu returns and the behavior of it so right over here it tells you that find by so in our example find by text returns a promise so that should tell you right off the bat that it is asynchronous okay get by and query by our synchronous okay so it returns a promise which resolves when an element is found keyword when an element is found so that's basically implying that sure maybe the element might not appear right away but eventually it will okay now here's the other thing that you also need to understand is that the promise will reject so typically that means that the promise is erroring out it's rejecting if there's no element found within a default timeout of 1,000 milliseconds or 1 second or if more than one element is found so similar to our get by uh query okay so basically the the reason why you would want to use the fine by query is whenever you're dealing with elements that take time to render to the document so in our example our elements appear instantly to the document they're all pretty fast right like our username just instantly renders so there's no logic that is occurring the username from taking you know 5 seconds from appearing to the document but you might write some tests that will often need to fetch an API or it will perform some kind of complicated logic that will cause the element to appear in the document after like 2 seconds like give or take 2 seconds or 3 seconds as an example I'm just throwing in a random number right so in a situation like that you want to use fine by queries because it allows you to wait a certain amount of time to search for the element to appear into the document okay so for example I could use find by text instead of query by text or get by findByText example text so let's say for example I'm going to remove this whole thing and I'm going to go ahead and call screen. find by text and then pass in my text and in the dev that I want to search for and then remember that find by text is a synchronous it returns a promise and you can see over here Returns the promise now what I want to do is I'm going to go ahead and copy this and passes into expect and paste this right over here but keep in mind that this is a promise so by just passing this right over here or I'm sorry this returns a promise so by just passing this call over here I'm trying to write an assertion on a promise not the actual value the return the resolve value itself in other words the actual HTML element that we expected to return so I need to actually await this call so I can add the await keyword in front but we need to make sure that we're inside an asynchronous function so I'm just going to go ahead and add the asyn keyword in front of my function for the test itself which you can do and then now what I can do is I can call 2B in the document just like this and I'm going to save this and when I look at my test let me go ahead and just run this again you're going to go ahead and see that it passes and now this works perfectly fine let me try to make it fail and now you can see notice how this time the test actually uh took some time to actually execute I don't know if you may have noticed but there was like a little spinner I can let me try rerunning it again you see how right over here there was that little uh spinner that was occurring so it it was waiting up to uh I guess 1,000 milliseconds I guess it kind of went a little bit over but that's okay it was basically waiting 1 second to find that element and it wasn't able to find it as you can see over here in the documentation it clearly tells you that the default timeout is 1,000 m seconds and then uh it rejects okay so that's the reason why right now our test it tells you that it was not able to find the text an and devs now what I can also do additionally is I can pass in a second argument and I can go ahead and set the timeout uh let's see I guess not here but let me do let me just pass in an empty object and then let's do timeout and I'll do 5,000 milliseconds so we'll give it some more time just to show you that that's why this is spinning and now you'll notice that when I restarted the test it took 5,000 milliseconds and then it rejected okay there you go you can see right over here that it's giving it enough time 5 seconds for the text to appear in a document okay I can set this to any number I want I can set this to 10,000 if I want to but I'm not sure vest will allow that I think vest has a default value for tests yeah you can see right over here that uh it seems like vest does have it set to it does have it capped at 5,000 milliseconds so you could change if you want to uh I believe right over here in the test you could set the time out to whatever you want so I'll set this to 20 ,000 milliseconds by default it was five so now you can see that let's run the test again though I may need to fully restart my test because I made changes to the configuration so let's run it again and now you can see that it is running longer than 5 seconds and it's going to be it's going to time out at 10 seconds okay and you can see that it took 10 seconds to search for the element by its text an inadev and it was not able to find it so it just errored out it just it just rejected okay so hopefully this proves to you that this is indeed why we would want to use find by text whenever you're dealing with elements that may not instantly appear in a document okay so let's just pretend like this is some kind of API call and then finally we get the text is appearing into the document right so what I'm going to do is I'm going to change this back to anad Dev and uh what I'm going to do is I'm I'm going to go ahead and uh render this username to the document but only after uh 5 Seconds have passed now the way I'm going to delay the render of this username is like this I'm going to go ahead and Define some State I'll just call this uh I guess uh timer P set timer past VI State and then I'll just call I'll just set this to to be false I'll go ahead and use uh a use effect hook CU I'm going to perform a side effect I only want the side effect to run one time I'm going to go ahead and call set timeout so basically this is how I can delay uh the execution of this call back so I'm going to set this to 5,000 milliseconds so after 5 Seconds have passed it's going to go ahead and execute this call back right over here and all I'm going to do is just call set timer pass true and I'm going to set the timer P state to True right over here okay and then I'm going to go ahead and conditionally render username so timer p and username just like this okay so now Watch What Happens let's see let's go over here so now our text our username is going to render but only after 5 seconds so let's go ahead and you can see that our our test already passes but let's just rerun it again and now you're going to see it's going to take up to 5 seconds and after 5 Seconds it was able to find that username because that username it took 5 seconds for it to render because when the component renders the current state of timer p is false so the username is not being rendered okay and also remember that when the component first renders it's going to go ahead and invoke this callback for the use effect hook so it calls set timeout uh it calls the Callback function of set timeout after 5 Seconds have passed and what happens set timer pass is called it updates the state to true and then when the State updates it's going to go ahead and render and then render username okay so hopefully this makes sense I could change this to literally any value I want so 1500 seconds I'm sorry 1500 milliseconds and then you'll see that the component uh let's restart the test again you'll see that the test will pass and it'll and it will basically uh pass after the amount of time it took for the element to be found so since I rendered the element after 1500 seconds you can see that it no longer is in this pending state for it to pass after 1500 milliseconds because it was able to find that element so it is I believe it is you know trying to actively find it periodically within that time span so hopefully this shows you how this works and again you can pretend like this is some kind of API call that is happening and then once the API call is done it's going to go ahead and render that data to the document and there we go we found it okay and for example I can change this timeout to 1,000 milliseconds or I can just remove this and have it be capped the default which is 1,000 milliseconds and you'll see our test is going to fail because it took our it it took 1500 milliseconds for this username to be rendered but the default timeout for find by text is 1,000 milliseconds okay so after 1,000 milliseconds it's just going to error out okay so this is just a tip so in case if you have something that may take longer than 1,000 milliseconds definitely make sure you pass in that third argument and set the timeout field do however long you think you may need okay so hopefully this makes sense now I did spend some time teaching you about how to actually test your More examples of Testing components with basic stuff right and I also wanted to make sure you understood how to use the different types of queries such as get by versus query by versus find by not understanding when to use which one is is a very common mistake that many developers run into and it leads to writing poor tests with inaccurate results so it's important to understand the difference between all three of them so I'm going to move on and show you more examples of tests so I'm going to show you how I can test a more complicated component that has a bunch of more different elements so for example I'm going to show you how I'm going to test this user details component in order to do that first I'm going to render this component to the document so that way you actually can visually see what this component looks like now the way that we render this component we actually do need some State because if you haven't been following along with the entire tutorial you may have missed on how this user details component was actually supposed to be used so it was actually a component that is supposed to be rendered uh based on a a list of users so what I'm going to do very quickly is I'm going to Define some state and I'm going to call the dispatch function set users because our user details component actually took in this set users function which is a dispatch function or an updator function to update the state of the users array itself okay so what I'm going to do is I'm going to go ahead and set a fake user we'll do ID of one username an the dev and then email anen gmail.com okay and these are all of the fields that we need need for our user object because remember the user details component it takes in two props a user object and the dispatch function and that user object needs to have an ID username and email property okay so let's go ahead and write down over here and notice how I comment out a lot of stuff in my app component because I don't want to overwhelm you all so here's what I'm going to do uh let's see I'm going to go ahead head and do this uh I'm going to go ahead and render the users so users do map and then we're going to go ahead and pass in our call back and then we're going to transform each user object into a jsx element so let's set the key to user. ID and then we'll pass in the user object like this and then we'll pass in set users and that's just going to be this dispatch function over here that was returned from the UST State call hook or the UST State hook call okay and then if I show you this you'll see that this is what our uh user details component looks like and again if I have multiple users there will be two users appearing okay we're only going to stick with one for now so when I click edit I can edit the username I can go ahead and edit the email address whatever I want right very very simple stuff okay and I can also delete this so what I'm going to do is I'm going to show you how I can write unit tests on this component specifically the app component because I want to make sure that I am testing the logic of this list of users okay I want to make sure that when I click on this button that I have these input fields and when I click save it's going to actually update the state of my username or it's going to actually update the text in the document okay cuz we want to test for behavior and not for implementation so the component under test is going to be the app component so what I'm going to do is inside my Snapshot well not not snapshot in my test folder I'm going to create a new file called app. test. jsx okay and again like wherever you are implementing this logic right over here so wherever you are rendering user details uh that is the component that is going to be under test which is going to be app in this case okay so what I'm going to do is this I'm going to go ahead and import my functions that I need from vest so I need expect it and uh describe so I'm going to go ahead and call the describe function and I'm just going to call this app and then I'm going to use the it function to create my tests so we'll just call this should render users okay and let's see so now we also need the other functions we need render and we also need the screen objects so I'm just going to copy this whole line and whoops paste this right over here and we also want to import the app component as well CU that's the component under test so let's import app from uh app just like that we're going to go ahead and call the render function and just pass in the the uh the app node the react node over here let's go ahead and run our test let's see what happens okay let's see here you can see that there is there are some errors already so we'll run npm run test okay so uh let's see so I ran both of our tests and then it failed on the app. test. jsx file it failed on this test over here okay so what exactly is the problem well right now the problem that it's telling you is that it's complaining about this used navigate hook being called outside of a router component and the reason why this is happening is because in previous sections when we were going over the react router uh we were actually wrapping the app inside the context of our router which happened right over here and since we are rendering app outside of the router provider and we're trying to use the use navigate hook outside the router context that's the reason why it is complaining now I'm going to go ahead and just temporarily comment this out because I do also want to show you how we can write tests uh with react router itself so I'm just going to comment this out temporarily and I'll go back to this later okay so I'm going to go ahead and Save this and what I'm going to do now is I'm going to go ahead and type npm run test but I want to actually only run the test on the app uh for the app file itself so I'm just going to do app. test. jsx or you can use a regular expression and now this will only run test for app. test. jsx and now I can see it passes okay which is good I believe it still makes the API call um which is another side effect that we probably don't want to happen in our test because what we want to do in unit tests is we want to simulate API calls and not actually make a real API call because right now you can see that in our app component we have this use fetch user hook being called which of course is making this API call to the Json placeholder API it fetches a user in a in a real unit test or in a unit test you don't actually want to make real API calls okay the purpose of a unit test is you want it to be fast you don't want it to actually make an actual real API call because that could actually delay your unit test you want them to be fast okay later on I'll show you how to use a mock service worker so for now I'll actually just comment this part out and I'm just going to comment out this whole thing okay and uh I'll comment out user data as well okay so let's just go ahead and make sure our test works okay perfect so our app uh test works and let's just quickly I'm going to go ahead and get the container one quick thing that you could do all the time to ensure that your component is rendering properly is you can use a snapshot test like how I showed you earlier on to verify that the correct elements are being rendered so if I click on this snapshot okay there you go you can see that my user details component was in fact properly being rendered because I can clearly see the username the email address and the ID as well as the button so this verifies that the elements are in fact being rendered to the document okay I'm going to go ahead and just I'm just going to I'll leave this alone for now okay so now what I want to do is I want to write some tests right now okay what tests do I want to write so a lot of times some people might be confused with what to test so think about this anything behavioral wise on your elements you want to test so what do I mean by that well in react testing Library it focuses on behavioral testing not implementation testing so what that means is you want to test for Behavior so in other words whenever you click on a button what is the behavior after you click on the button so for example if I click edit okay what is the behavior after I click on edit what is the expect ation that occurs after I click on the edit button well visually as a user I can see that a couple things happen I can see that the save button appears and then I can see that uh two input Fields appear that replace the text so for example the username uh has this ants in the dev field and then or this username field that has ants in the dev and then so there this email field it has this email address populated in there as well so that is the behavior that is the expected outcome of whenever I perform some type of action in the document okay now when it comes to implementation details testing or implementation testing what that typically means is you're trying to test the underlying details of the component and not the behavior so rather than testing that an an element appears in the document you're trying to verify that the state of a variable was modified okay so let's think about the code for a second let's look at the implementation details right so in the user details component let me go up top over here you can see that we have some State I have this is editing State variable that's a boen and you can see that when I click on this button what exactly happens well when I click on the button the set is editing dispatch function is called called which toggles the mode the it toggles the is editing value from True to false false to true so if the value was false now it's true if the value was true now it's updated to false okay so when it when we talk about implementation testing what that means is you're typically trying to test for things like the value of the states such as okay am I verifying the state of is editing is it false or is it true or what is the value of username what is the value of email you don't want to test for these implementation details because as a user you only want to be concerned with what is actually being displayed what is actually happening to the actual document itself right behavioral driven testing is a whole other philosophy over implementation details testing and the thing with implementation details testing is that the implementation can change over time for example I might make changes to my state variable is editing and the way that I render my uh the way that I render my save button because right now the save button is only rendered when is editing is true it's being conditionally rendered the way that I might render my save button could change it could not be based off of this state variable anymore okay and by testing for implementation I have to also change the test over time as well whenever I change my component logic but if I test for Behavior it decreases the chance of me having to test or rewrite my test because we're testing for Behavior so what appears on the screen I don't care about what the state value of is editing is I just care about if this save button appears to the document so hopefully that makes sense if you have any questions or if you any clarification post a comment down below and I'll be more than happy to explain the differences okay let's go ahead and move on and let's go ahead and write our first test so what I want to do is I want to write an assertion so let me refresh the page what I want to do is I want to write an assertion that whenever I click on the edit button the save button appears okay so let's do this so what I'll do is I'll leave this test alone and then I'll create another test down over here because why not you can create as many tests as you want and it's always good to test for different things in its own individual test itself self so what I'll do right now is I'll write a test and then I'll call this test again you want to be descriptive well you want to be concise right you treat it like this treat your test names like a git commit message if you're familiar with Git which I'm sure many of you are you obviously don't want to write a whole essay you just want to write something short that describes what the whole purpose of your changes are so in this case I'm going to go ahead and keep it nice and simple I'm going to go and say it should uh it should render save button when edit button is clicked and this is you know short and simple okay it should render save button when edit button is click and it's important to have your tests uh the names make sense because often times experience developers what they will do to understand a brand new code base is they'll look at the tests and they'll read it to to understand what exactly the behavior of each part of the application is so for example if I didn't understand you know what this uh react application was supposed to do I'll go into each test for a component and I'll read the test itself and if I read this I'll say okay it should render save button when edit button is Click so that tells me right off the bat that if I go to this component on the screen when I click on the edit button the save button should be displayed and slowly this knowledge builds up and that's how you become experienced with a brand new codebase that you are not that you were not familiar with before okay so what I'm going to do is first we always need to make sure we render our app because in each test itself it's its own environment right you have to always make sure you render the component that you want to test so I'm going to go ahead and render app but this time I'm not going to uh do anything with the return value I just want to render it to the document now remember that our app component is pretty straightforward there isn't any complicated logic we have state that is already defined with a default value with one object in the array and it's just rendered to a document there's no uh data fetching going on we're not waiting like more than a second for our data to be rendered it's almost it's almost as if it's rendered instantly right and well I mean it's going to be rendered uh fast enough that we don't need to use find by Using getByRole to query Buttons queries instead so we can actually just use get by so what I'm going to do is I'm going to use screen get by and you're probably wondering well now which get by query should I use should I use get by text and then pass in edit which is the text of the button that I'm trying to search for right that's the text of this uh edit button right over here okay now while you could do this like you technically could do this right let me show you uh the return value of get by text you'll see that when I use get by text and pass in edit this will actually give me an HTML button element uh right over here let me restart the test and you'll see that right over here uh right over here it logs HTML button element so we're basically searching for any element by the text and that element could be anything in this case it just happens to be a button now while this does work you shouldn't do it because there actually is priority whenever it comes to certain elements that you're trying to search for so what do I mean by that well according to the react testing Library they actually have certain principles and they describe to you what type of query you should use based off of the element that you're trying to search for so for example uh right over here you can see that get by text is like number four out of uh I guess all five of these rankings right so for example right now we're trying to search for a button okay in case if you didn't know uh the button element actually has a r property okay which tells you the purpose of the element itself what is the purpose of this HTM element well the purpose of this is a button so it's meant to be clicked on right so what you want to do is you want to use the get by roll or query by roll or find by roll query whenever you're trying to search for a button okay and it even tells you right over here uh this should be your top preference for just about everything there's not much you can't get with this uh so like right over here get by roll they show you an example of how to search for a button so you just literally pass pass in the r itself and then the text for the button and there's also this section that gives you a bunch of different roles so for example you can search for buttons checkboxes links menu items so anything that has a rooll itself you want to use the get by roll that's like the number one priority that you want to pay attention to okay so let's go back here and what I'm going to do is I'm going to remove this part and we're going to go ahead and call screen get by roll and we're going to go ahead and specify the RO that we want to search for which is going to be button again there are a bunch of different ones so just pick the one that you ideally want to search for in our case we want to search for a button so I'll specify button and then now keep in mind that your application the component that you're rendering may have multiple buttons right in our case my component my user details component has two buttons so how do I know which one to to search for well remember that there was this second argument which was an options object and the name property allows you to specify which button by the text you can search for Okay so for example I can pass in name and what I can do is it tells you that you can filter the return Elements by their assessible name so in our case uh the edit button the name of it that we can use is literally just edit okay the text of this button itself okay so let's go ahead and go back to our test and for the name I'm just going to set this to edit just like that okay and now what I'm going to do is I'll go ahead and just write a console log just to show you the return value of this and since I know that this button in fact does exist in the document this test is not going to error out let me run the test again okay and you can see right over here it was in fact able to find the element okay you can see that we have a bunch of different properties on this element as well and it should show the text somewhere for this button yep children edit that's the text of the button over there so that is the correct button okay so what exactly do I want to do with this button now well first let's go ahead and just copy this and I want to store this in a variable so I'll just call this edit button cuz I possibly might want to reuse this edit button over and over again and then what I want to do now is I want to click on this button so this is the part where I'm going to teach you how to actually simulate events specifically click events on your components on your elements so right over here what I want to do is I want to click on this edit button we have the element already we want react testing library to actually click on the button itself so the way that we can do this is as follows so what we want to do is first we need to actually install the user event Library it's part Firing User Events of the testing Library API it's just kind of like a uh companion library is the way that they describe it so by default you don't have user event but you have to install it okay um it's still made by the same creator of uh react testing library but it's just in its own separate package Okay so so what we're going to do is we're going to install this user event package so I'm going to go ahead and type npmi hyen D at testing hyen Library SL Usery event okay and then the way that we're going to import it is like this import user event from and then the name of the package so I'll just copy this part over here and then what I'll do is I'll import it like this so import user event Simulating Click Event from and then at testing Library user event okay so what I'm going to do is I'm going to reference user event because this gives me a bunch of different uh methods that I can use so you can see by just hovering over this intellisense you can see that we have clear click copy cut double click hover keyboard paste pointer a bunch of methods and events that you can simulate or methods that simulate events right so the one that we want is Click because we want to click on on a button so user event. click and then we're going to go ahead and pass in the element we want to click on and you can pass in literally any element you want it doesn't have to necessarily be an a button it could be like a div for example so you pass in that and then there are also options that you could uh pass if you need or we don't need any for now now this click event is asynchronous it returns a promise so we want to make sure that we handle that accordingly some going to add the as keyword in front of my callback function that I'm passing to the test and we'll await this call okay so after I click on the button we can expect that the save button will appear in the document right well at least that's what we can see when we actually interact with the component itself and then that's what our test is supposed to be testing for so when I click on the edit button the save button should appear so we actually have to to write the assertion for that now so again we know how to search for buttons in our in our uh in our test okay we use get by roll so what I'm going to do is I'm going to go ahead and do this const save button equals screen get by roll and then the r name is button and then now and for the name the name is going to be save because that's just the name of the butt right over here okay and then what I'm I'm going to do is I'm going to write an assertion so expect save button and then we're going to use to be in the document matcher okay so just to recap what's going on is first we are searching for the edit button we click on the edit button we have to await this call because it's asynchronous and then after this has been clicked on we're going to go ahead and search for the button uh the save button and then we're going to go ahead and write an assertion that that button is in the document we're not going to do anything with a save button okay the whole purpose of this test is to just verify that the save button appears so let's go ahead and see if our test actually works so npm run test and then I'll type in the test file name and let's see if it passes and there we go it passes but what I'll do additionally is I'll go ahead and negate the test to make sure that it in fact was passing correctly so you can see that it says expect a document not to contain element but it did in fact find a button uh with the save name over here okay so this was passing correctly so there we go so this test verifies the functionality of the edit button so when I click on the edit button the save button appears and then this test verifies that so we're good we're done with this test we don't need to do anything more now obviously we still want to make sure we're testing other parts of this component because for example I want to make sure that uh these input fields are also there but I don't want to write all of that assertions inside this test because you want to keep your tests clean and concise you don't want to write like 500 different assertions in one single test okay so what I'm going to do now is I'm going to go ahead and write another test and this time I'm going to go ahead and say it should uh display username and email in put Fields when edit button is clicked okay okay so there we go now one thing that I also want to mention is that sometimes uh you might run into a hard time where your name of your test it's hard to kind of like keep it short so one thing that I like to do is I like to actually use another describe test Suite inside my already existing test Suite over here so describe app and then inside over here I have another test suite and then I can just label this test Suite as uh something that groups together uh similar tests right so what do these two tests have in common well they have in common the behavior of whenever the edit button is clicked so what I can do is I can say okay well this test Suite is supposed to be for uh edit button okay so the purpose of this specific test Suite is to basically tell me or another developer that's reading the test that okay everything that's within uh this test Suite has to deal with the behavior of edit button okay so what I can do now is I can just copy these two tests and I can paste it inside here and now I don't even need to mention the edit button at all okay so uh let me do this uh I can remove let's do this uh let's see edit button describe edit button is clicked okay so describe edit button is clicked should render save button so basically this test Suite the name of this test Suite is allowing me to kind of like prefix or describe each test that is occurring so it saves me you know the ability to write like a long description okay so I'm shortening this part and I don't have to mention the edit button because I'm inside this test Suite which implies that everything that I'm dealing with is the edit button itself so now I can go ahead and remove this it should display username and email input Fields so notice how now it's a lot more shorter okay so hopefully this part makes sense so let's go ahead and actually continue with our test so we'll go ahead and render our app uh we do still need to search for the edit button so I'll do that right over here and what I want to do now is I want to click on the edit button so I'll do that as well so I'm just going to copy what I had in the previous test because it's all redundant and now this time instead of searching for the save button we just want to verify that the username and input fields are in fact in the document so the question is can we also Querying for Input Elements use the get by roll query to search for our input elements and the answer to that question is yes you can now remember that according to the documentation the official documentation of rea testing library is the priority is get by rooll and then get by label text is the second one so technically you should use get by roll over get by label text to search for an input field in case if you forgotten or didn't know that input Fields can have a label associated with the input field itself for accessibility so when you click on the label itself or if you hover over it or if You tab to it and then you hit space bar it will actually focus on the input field itself but not all the time you will have a label text so I'll show you how we can do it by using get by roll okay so here's what I'll do I'm going to go ahead and do screen get by rule and the rule of our input field is text box okay text box just like that and now for the options we need to make sure we specify which text text box which input field we're trying to search for right because there's two different ones there's this one and there's this one they're both different so we need to basically filter it out essentially so we can actually use this name property okay now this actually requires us to set an ARA label on the field itself on the input field itself so what we can do is this let's go into our user details component and for this input field what I'll do is I'll set ARA label to username so that way this will actually give the uh input field a name called username and then I'll do the same thing for the email input as well okay and you'll notice that when I actually go into the browser tools so if you see right over here the name of this input field this username if I were to remove this Aro label you'll see that the name is an empty string okay so we can use this AAL label at the very least to search for the element by the text box if we don't have a label okay but again like I said get by roll has a higher priority so you should use that so what I'll do now is I'll set the name to match the name of the input field that I want to search for so that's going to be the value of this AO label so username and then we'll do username like that and if I go ahead and just cut this I'll do expect paste that in there and I want to verify that this is in the document so we'll do 2b in the document and let's just see our test we can see that our test passes and of course if this test if this uh screen uh get by roll call didn't find the text box it would throw an error okay remember that's what the get by query does so this test is passing if I were to do not to be in the document it would obviously uh fail because it is finding it okay so let's do the same thing for our other field so screen uh uh. get by roll textbox and then the name will be email to check the email field itself and there we go no errors with that whatsoever if I were to pass an emails with an S it goes ahead and it errors out and you can see that it actually gives you some decent I would say this is pretty good feedback so it tells you the accessible roles so you can see that we have our buttons and the name of the buttons are edit and then for the input fields we have username and email and that was set by the ARA label not the actual name attribute itself okay so hopefully this makes sense let me go ahead and just remove that and yep everything passes perfect now as promised I will show you the alternative way to search for input Fields whenever you have a label okay getByLabelText example now you could still use get by rooll because like I said it is a higher priority versus get by label text but I think get by label text is not a bad way I mean it's it's not it's not like it's a bad thing to use get by label text right because it is a lot easier to use get by label text when you do have it that is so here's what I'll do uh so right now I am rendering a bold tag for the username so why don't I do this why don't I conditionally render um a label so if we're in editing mode because remember this is editing State variable is what is uh is what is allowing us to conditionally render the input Fields so when we click on the edit button we're setting the state of is editing to true or we're toggling it basically okay so let's do this when we are in edit mode so when is editing is true instead of rendering the Bold element which is what it's currently rendering we'll render a label so if is editing I'll use a conditional uh I'll use a Turner operator for this uh so what I'll do is this if is editing is true I'll render a label otherwise I'll render uh a bold tag right over here for username uh so we need the HTML 4 attribute and that's just going to be the ID of the input field that I want to associate this label for so username just like that okay and then let me go ahead and just use the long syntax to render this label so that way I can just do a username let me just see what that looks like in the document real quick okay username let me add a colon and a space as well okay there we go and then let's do the same thing for email address so let's do this okay and then just copy this paste that there change up the attribute value and then the name of the label okay so now if I look at my app you can see now when I am not in editing mode so is editing is currently false it's going to go ahead and just display the Bold tag right over here when I click edit these are now labels and you can verify that by just looking at the document itself you can see we have our labels okay and notice how if I click on this it'll focus on the actual input field so what what we're going to do is we're going to use the uh get by label text query to get the actual input field itself so this is what I'm going to do I'm going to go into my test and I'm going to go ahead and modify uh this call so instead of get by roll I'm just going to do screen. getet by label text so what exactly is the label text well it's literally what this text is over here so I can be very specific I could do let's see we're trying to search for the username I do username colon and the space you have to be very specific so I'll comment this part out over here so watch what happens if I just did if I just did username okay it's going to go ahead and fail unable to find a label with a text of username if I did username colon let's see what happens it passes so I guess it ignores the space it doesn't really care about the space but as long as I have the colon then that works okay and we can do the same thing for email so I'm just going to copy this part over here and then we'll do email col in like that okay there we go so we're able to find uh both input Fields based on the label text and again if you want to be uh if you wanted to make sure that your test is correctly passing okay you can even just modify just a little bit and see what see what happens to to the text or see what happens to the test so right over here I added a space and uh let's see what happens unable to find a label with a text of username colon space I wonder if it trims the space itself because it doesn't seem like it trimmed it over here uh cuz if I were to remove the space let me see there is a space over there so not sure why yeah so I don't know I don't I wonder if it trims the text but anyways so you can see that this works with get labeled text and again if you have the opportunity to use get label text personally I would prefer using get label text over get by roll um but if you don't have a label then you you can just use get by rule and that would be perfectly fine okay so hopefully this part makes sense now before we move on completely with uh Testing Multiple Elements of Same Instances labels and input fields and searching for them I did want to show a situation where you could possibly have conflicting uh elements right because keep it mind that right now we're only using one user that's being rendered to the document and we only have one username field and one email field but what if we had two users displayed to the document and then both of those users are being edited simultaneously so I'll show you an example So currently I'll go into my user details component or not here but the app components and I'll go ahead and just copy this user and I'll just change up the data so I'll just set the username let's do uh Michael so we have two users that are rendered to the document right and then you'll see immediately that our test actually just fail instantly because we're trying to find a button with uh the name edit but it tells us right over here that it's not it's it it it found multiple elements with the roll button and name edit okay so you can see immediately that we have a problem so in situations like this how do you ensure that you can set up your code in a way that we can actually test it correctly because this is actually more so a problem with the way that we are rendering our elements rather than the way that we're writing our test keep in mind that when you are writing tests right the more difficult that you make your components the more difficult it will be to test it okay so what we want to do to fix this well there's a lot of ways that we can do this right like for example like if I wanted to what I could do is I could use get all instead of just get by right get all by roll get all by label text okay and then what I can do is I can you know just write some assertions on all of the roles or all the buttons to verify that they're all in the document but I have a better idea what I'll do is this I'll go ahead and for each button that I am uh displaying to the uh to the document okay one thing that you could do and Data Test IDs again there this is one thing that you could do there there are many ways that you can do this but one thing that you could do is you could actually use a custom data test ID to verify which button is which so you're able to distinguish each button for each user right because we have one button for this user or a pair of buttons for this user and then we have a pair of buttons for this second user okay so what I like to do is I like to set a data test ID so you can just go to the button or any element and set this data test ID attribute right over here okay and then what you can do is you can set the value of this so I can set this to anything that I want but remember that you're going to have multiple user details components being rendered okay which means that you're going to have multi multiple edit buttons that are rendered one for each user so what you can do is you can actually uh do this you can do edit button or edit BTN and then the ID of the user like this I will mention that something that you should keep in mind is that you often shouldn't you should avoid using uh test IDs um if you don't need to right because according to the documentation um you can see that right over here that uh get by test ID is actually the last recommended query that you should use and they even tell you that you should only use this where you can't match by rooll or text okay or it doesn't make sense uh in example the text is dynamic so if you can use get by roll you should so I'm only just showing you this as an example I'm not going to actually recommend to prioritize using a test ID over uh get by roll I'm just showing you this as an example okay so I'm going to go ahead and give this a unique test ID because each user will have its own edit button button same thing with the delete button as well so I'll copy this attribute paste this here and I'll just changes to delete button and remember that each user will also have its own uh username and email input Fields as well so we can also set IDs on their data test IDs on those fields as well okay but before I do that though let me go ahead and go back to my test and I'll go ahead and actually just just uh I'll comment this test out cuz I know this is going to fail but I want to just go back to this first test that we have inside this edit button is Click test site so our test is still failing getByTestId example because right now uh we're still using get by roll but this time what I'm going to do is I'm going to use get by test ID instead and of course this requires us to know what the test ID is and remember our test ID our test ID is going to be dynamic because we're using the users's ID prefixed with a hardcoded string edit button okay so if we want to verify that the edit uh if we want to verify that the uh the edit button for the first user is in the document we just have to do edit button and then the ID of the user which we know is going to be one because we have it hardcoded so what I'm going to do is I'll just do get by test ID edit button one and then I'll do the same thing down over here screen get by test ID edit button two and now you'll see that our test should uh pass but the snapshot is failing um you know what I'm just going to go ahead and just update the snapshot so now you can see that my test is passing because I have everything hardcoded and if you look at the snapshot you can see that everything is uh obviously different now okay so like I said I would not recommend doing it this way because one you're hardcoding this and again get by test ID has the lowest priority and you should only do this if you cannot find the actual element using any of these uh using any of these queries okay so only use get by test ID if you just cannot match by the role or by text so now okay is there a solution where I can search for each individual button for each user well in the way that we set up our uh in the way that we set up our UI no because keep in mind that without this test ID there's no way for us to know which butt is unique to the user right like for example if I just undo everything right now remove all of the um let me remove all of the test IDs okay let me undo everything that I had in here if you were just to look at this right now you wouldn't be able to tell which button is associated with which user unless if you were to you know set the text of the button to include the ID of the user but obviously you wouldn't want to do that because it just doesn't make any sense like the user is going to be confused like why am I seeing uh the ID on the edit button it doesn't make any sense right so there are there are different ways that you can tackle this there are there are a bunch of different ways that you can tackle um this specific uh this specific problem now what I would recommend and again there are a bunch of different solutions out there but I think one of the best solutions that I would recommend is this so we know that the user details component the amount of times it is rendered is based off of the number of elements in this users array okay so instead of associating a data test ID with every single uh button because that's what we were doing before and then same thing with the input Fields instead of doing that what I would recommend is we can actually associate a data test ID with the roots element of our user details component so this div right over here I can add a data test ID to this and then I can just call this uh user details and then user. ID just like that so that way I am uniquely adding this user details uh data test ID to each user details component and then it'll look like this in the document you'll see user details 1 user details 2 and if there are 100 uh users it'll just go all the way from one to 100 right and then what I would do is this I would query for the user details uh I would query for the user details by the ID by the data test ID okay so I'd query for the component by the user details ID and then I would use using within() to search elements inside an HTML Element the within API to query for my buttons and my input fields in that specific element okay so I'll show you what I mean by that so what I'll do is this I still want these I still want these uh tests to pass so here's what I'm going to do I'm going to make my I'm going to make my uh component a little bit more Dynamic so watch this here's what I'm going to do okay I'm going to go ahead and take a users prop into the app component and uh let me go and do this uh user I'll call it users data and then I'm going to go ahead and pass user data to the default state of use state so whatever I'm passing into app as a prop which is going to be an array of users will be set as the state for users itself so I'm going to copy this whole thing okay and then what I'm going to do is in the let's see in the in the entry point of my of my app where I am rendering the app element so right over here in the router I'm just going to pass users data like this okay and then that will require me to pass this data in my test right over here so I need to pass users for this I'll just pass an empty array because I I'm not really testing for anything over here and then let's see for this first test over here I'm going to pass users data but this time I'm only going to pass an array with one element just like that so that way my test is still passing cuz I'm going to have separate tests okay so our test should pass let me update the snapshot cuz that's what's feeling right now uh let's see what's going on [Music] here um what's going on oh it's because I need to update this part can I read properties of undefine reading map um users data is complaining about something being undefined let me double check my app components so we pass that in here which is an array we know that it's going to be an array no matter what then users. map uh interesting I'm not sure why that is erroring out oh I'm sorry it's failing over here users data sorry about that okay there we go I knew something was wrong with the way that we did it okay there we go so we have users data set as the prop and passing in this empty array over here I just I just misspelled it should have been users data instead of users okay good so all of our previous tests pass I don't want remove this cuz I want to keep it as a reference so at least you all can still see it now I will just update uh a couple things what I'm going to do is because now we're dealing with uh altering our mock data over here because right now this is mock data right and we have different scenarios we have a scenario where we have only one user but now we're going to write tests where we have multiple users instead so our our scenarios are going to be a little bit different so what I'll do is this I'm going to go ahead and take my whole describe and again you can have as many test Suites as you want you can have you can have an infinite amount of test Suite hierarchies so I can wrap multiple describes within a describe and I think it's good practice because again you want to be specific with what you are testing and what what your scenarios are so over here I'll just say um when describe uh I guess the best way that I can uh give this name is uh let's see when users is only one okay and then what I can do now is my tests are still going to pass and then what I can do is this you know what I don't need this snapshot anymore I'm just going to remove that because that's an unnecessary test Suite so describe when users is only one or when there is only one user I think that's a better description and then now I'm going to write another describe when there are two users okay so we're we're describing different scenarios and we're testing different scenarios and again I think it's important to test every possible scenario you can think about because this will cover every single uh angle of your application again you're not trying to aim for a 100% bug-free codebase because there's no such thing as that there's always going to be bugs no matter what you're just trying to reduce the amount of bugs that your application could possibly be exposed to so even if you have a code base that is 99.1% bug free that is still fine okay again there's no such thing as 100% bug free there's always going to be bugs so when there are two users and then what we'll do is this our test is going to be a little bit different this time so what we're going to do is we're going to go ahead and uh let's do this I'm going to copy that and I'll say it should click edit button for first user okay so we're going to go ahead and uh inside oh I need to also call the render method as well so inside here I'm going to call render pass in my app and again we need to pass in uh the user data prop top but this time we need two users because we have two users okay otherwise our test wouldn't make any sense right so we'll do ID of two and then we'll do username Michael and then email Michael gmail.com okay now ideally what you could also do is you can also have another test before this one that verifies that there are actually two users that are render to the document so very quickly what I could do is this I can write a test should have username it should have two users in it should have two users and again we don't want to test we don't want to actually verify that the array has two elements we just want to test the behavior of the document itself which means that there are two there there are users with two there there are two user dreams display to the document okay one is ANS and Dev and the other one is Michael so the best thing to do is first let's let's render whoops let's render the app and then what I'll do is I'll say expect and Screen get by text and in the dev to be in the document and I'll just duplicate this test for Michael um yep Michael okay so this test should pass okay let me update the snapshots because we don't have them anymore and then notice how if I set this to Michaels this will fail okay yep you can see that in the actual snapshot or in the actual render itself you can see that we have uh username Michael over here and then username Anson the dev over here okay so this is kind of like an entry test like you're verifying the most basic thing before you test any other behavior and that is verifying that both users are actually in the document okay now what I'll do is I'm going to test when I click on the edit button for the first user so I'm rendering the I'm rendering the uh app and then what I want to do is first let me make sure that I have my data test ID I do so what we're going to do now is we're going to use multiple different uh queries okay we're going to use expect and we're going to do screen get by test ID and then the test ID for the first user is just going to be what we set it which is a dynamic value so it's prefixed with user hyphen details hyphen and then the ID of the user which is going to be one for the first user so we'll do I'll just hardcode this user details one expect screen. getet by test ID and I can write a bunch of assertions the first thing that I may want to do is verify that this actually exists in the document so I'll do uh user details equals that and then I'll do expect user details to be in the document and then our test passes okay great now this actually is a little bit redundant because uh get by test ID will actually fail so we actually don't even care about you know writing this assertion because this will fail if it can't find it in the document so if I set this to three this whole thing will fail so writing this assertion is not necessary so I know some of you might be you know eager to write a bunch of assertions but sometimes you can just skip writing specific assertions just because we know that get by will fail if it cannot find the element in the document so if this doesn't fail it implies that this was able to be found now what I'm going to do is I'm going to use this Within uh this within function we're going to need to import that from testing Library Dom uh so let's go ahead and import that real quick we're going to go top over here import from so at testing library and then for slom like this and then we want to import within let's see I'm not sure why that function doesn't appear um in Intel sense but it should okay it is being correctly it is actually part of it though I'm not sure why it didn't appear in intellisense but it is actually there yep within okay so what we're going to do is we're just going to use this within function and then literally all we're going to do is just pass in the element that we want to search elements from within that's literally why it's called within so all that means is we're going to search for we're going to query for elements that are inside this user details element which we got using the test ID so what I'm going to do is this within and then user details and you can use find by get by query by whatever it is that you want to use I'm just going to use get by and then this time what do I want to get by well again I'm trying to click on the edit button but you know this is not really a meaningful test so maybe I might want to change this to what we had above so it should click on the edit button for first user and save button appears it should click edit button for first user and uh this I I'll call this and display save button okay so within user details so within the first user details element that is rendered we're going to get the edit button by the roll so get by roll button the name of it was edit okay and then now what I'm going to do is I want to click on that button okay so we're going to do this const uh let's do user or let's do edit button okay and then what I'm going to do is I'm going to fire an event so that's going to be asynchronous let me add the ASN key word so wait user events and then click edit button and then now what I want to do is I want to verify that the save button appeared so what I can do is I can do the same thing I can use within so I can use within user details get by roll button name save and then additionally I can wrap this whole thing with an expect CU I want to verify that this is actually in the documents okay I know this was a lot but let's just make sure the test passes so okay there we go you can see that the test passes so when there are two users should have two users should click edit button for first user and display save button okay so let's walk through this step by step okay first what we're doing is we're rendering the app with two users passed in for the user data uh prop in the array we first get the user details for the user ID of one so that is going to be for uh ANS in the dev okay and if you want to be even more specific you can literally use the within query within user details and then you can do get by text and specify the username to verify that it's Anson the dev and not Michael that we're working with okay so uh let me do this get by whoops sorry about this it should be within get by text this whole thing inside the expect and then to be in the document and that passes um but though I do think a better I do I do think a better test would actually asserting that Michael is not inside this user details element because it shouldn't be right cuz Michael should be inside uh the element that is associated with user details 2 the test ID so what I'll do instead is I'll do within user details query by text and then Michael and then remember we use Query by text uh to assert that an element it's best used to write an assertion that an element does not exist okay so within this what I'll do is uh expect to be null like that okay and then you can see that the test still passes because this in fact does return null if I were to set this to be an the dev the test is going to fail because it there is actually the text an in the dev so that's the reason why this is not null okay so this asserts that we are in fact working with Anon to Dev and not Michael okay okay now we get the button that has the name edit that is inside this user details element which is associated with the user details one data test ID which is for our first user ANS in the dev okay so we get that specific individual button so it's literally just grabbing this edit button right over here and then we click on that button so we click on that and then the save button appears and then what we do is within the user user details element cuz we're still inside the uh the user details one element itself we verify that the save button is in the document now you don't actually need to even use within at this point because there's only one save button currently but if you want to be more verbose if you want to be more specific you can use within as well right like even if I did screen get by roll because there's currently only one save button right there's only one save button this would still pass but if you try to work with a second user you would need to actually use within because there are two save buttons in the document okay so hopefully this all makes sense so let me go ahead and just fix this back to have within just so that we're more specific and now you can see that we are able to uh handle the case where we have multiple users rather than one okay and if you want it to be even more uh Bo you can write a test to verify both users okay so this one and then this one right over here okay so now let's go ahead and actually do something with the save button right because so far we're just clicking on things we're not actually you know updating State we're not doing anything let's actually update the state by clicking on the save button and verifying that the username was updated right so let's go ahead and do this so let's see should click edit button for first user and display save button so why don't I write another test uh let's do this it should edit second user second uh it should edit second username uh and save okay so I'm going to go ahead and just add the Asing keyword for this call back function so this test what it should do is it should edit the second username and then uh and then save by clicking on the save button and then verifying that the username was updated in the document so there's a lot of redundancy with our uh with our rendering so what I'll do is I'll just copy this render this okay and then this time what I'll do is I'll get the the user details with the ID of two so screen. getet by test ID and then we'll pass in user details too because we have two users and then what I want to do is I want to grab the edit the edit button so uh what I want to do is this I will go ahead and do within user details get by roll button the name is edit and I want to click on this button so um I'm just going to go ahead and do this I'm not going to store the return value of get by roll in a variable like I have been doing previously because we're only really using it once so there's no point for me to store it so I'll go ahead and do await user events. click and just paste in this whole entire thing right over here because the the end return value is whatever get by roll returns which is the actual button element itself so we can just pass it in right over here so we're going to click on the edit button then what I'm going to do is I don't even care about verifying the save button appearing because we already verified that in our previous tests so we don't need to even we don't need to basically assert that again okay there's no point for us to do that okay and remember that by calling get by roll that and if it doesn't fail it pretty much implies that if it passes it implies that the button element was found so there's no reason for us to assert that the element exists because if it didn't it would just fail the entire test anyways because that's what get by roll does or that's what the get by query does so we we're going to click on the edit button and then what I'm going to do is I want to uh Target the username so remember the whole purpose of this test is to update the username I don't care about the email field that can be for a separate test so I want to Target the username field so this time what I'm going to do is I'm going to go ahead and grab the username field okay now you could get away with using screen and then get by label text and then specifying the username field itself because currently Let me refresh right currently or whoops sorry currently we are editing the second user and there's only one user there's only one input field for username right but again like I said you might have a point where you might have two username fields in the document and in situations like that you would want to make sure you use within to specify the user details component that you working with okay so that's the whole reason why we're even using this within uh function call in the first place so you could get away with doing just screen get by lab text cuz there is only currently one input field for username and one for email but if you were to click edit for both users then you would have trouble with that cuz now there are two username fields and two email Fields so we'll just be consistent and we'll just use within so we'll do within user details then get by label text and then username Simulating type event without the space and then what I'm going to do is I want to uh perform another user event so we're going to go ahead and do this we're going to do await user event this time the event is going to be type okay there are a bunch of different events for example you can paste you can cut which just will get rid of all the entire text you can copy uh I believe the best one that we would want is probably type so user vent. type okay and then uh I'll just take this whole thing within and then get by label text because remember this Returns the HTML input element for us paste that in there and then what I want to do is I want to specify the text that I want to type so keep in mind that uh we're actually just adding to the current value of the input field okay so what I can do is I can just type something like uh one two three okay so this will literally add one two three to Michael okay so now let's go ahead and continue so when I go ahead and type 1 2 3 in the label uh we want to make sure we click on the save button so what I'll do is this uh within we also want another uh user events so await user events click and then within user details we want to search for the the save button I'm kind of just uh going through this a little bit faster because a lot of this stuff is pretty much what we already covered already so it should be pretty straightforward if you understood everything before so within user details we're getting the save button for uh the user itself that we're editing so we click on that button and then now what we can do is we can write our final assertion to verify that the text was in fact updated and if you again if you look at it from an actual user perspective I click edit I type 123 I click save and then now the actual text should be Michael 123 instead of just Michael so what I'll do now is I'll actually write two assertions I'll I'll assert that the username field is not in the document anymore just to make sure that that username field is gone after I click the tech after I click the save button and then I'll assert that the username the the new username is actually in the document so first let's do this let's do uh let's see uh within or expect within user details we're going to go ahead and do query by roll button or I'm sorry not button uh query by label text I'm sorry query by label text and then username so we're writing an assertion that this uh this username input field is no longer in the document So within query by label text to be null let's verify that the test passes it does and if I were to negate this so do not. Tob null it will fail because it's not act because it's actually null okay expect you can see over here expected null not to be null which doesn't make any sense right because null is null null is not null okay so there we go we're verifying that the username field is not in the document that's great so now what I can do is I'll go ahead and write another assertion within user details we want to verify that the text Michael 123 is in the doc so let's do get by text Michael 123 to be in the documents let's see what happens uh there we go so it seems like get by text uh Michael 1 123 is in fact so Michael 123 is in fact in the document so it seems like the update was correct notice how now if I just Tred to do Michael it's going to fail because if you look over here it says unable to find an element with the text Michael and that's because the actual username is Michael 123 so I hope this complicated test I mean it's not really that complicated but once you get the hang of it it becomes easier right and that's the reason why I'm showing you these different scenarios when it comes to testing because the more difficult scenarios you test the better you become at it so I hope that this helps you better understand how to test your components even when you have more difficult scenarios such as having you know Poss possibility of multiple elements of the same instance of the component appearing in the document okay so I hope this all makes sense and we'll go ahead and move on to other Other queries examples now there are also a bunch of other different ways that you can query for elements with react testing Library so for example uh so far we've used uh get by rooll we've used get by label text uh we've used get by text there's also get by placeholder text so for example if you don't know what a placeholder is I'll show you very quickly so if you have an input field you can add this placeholder value and you can just type whatever you want enter data and if you go to the document you'll see that we have our input field and we have our placeholder value displayed over here and the moment that I type something that placeholder value disappears usually placeholders are useful to kind of like give a hint to the user on what to type in there like for example you see them often in a website that has a search box you'll see like a magnifying glass and it'll say search dot dot dot so that hints to the user that this is used for searching across the website okay so for example if I wanted to wrun a test to get an input field uh based on the placeholder value you would want to use the uh get by placeholder text query okay again the priority of this it's not really something that you would want to prioritize over get by roll or get by label text but like I said in your application not all the time will you have a label for every single input field and sometimes you may not be able to use get by roll so you can use get by placeholder text okay so I'll just quickly show you a simple example so what I'll do is this I'll go back into my components I'll create a very simple component uh I'll just call this uh test input field. jsx because I can't think of any other better name for this component and I'll just go ahead and do this give it an input field okay and then I'll go into my test folder I'll create a new file call it test input field. test. jsx and now we'll write a we'll write our test so so first I'm going to go and just copy all the things that I need so let's copy this um I guess that's it and now what I'll do is I'll write you don't even need a test Suite sometimes you don't even need a test Suite if your test is as simple as possible you can just easily just write uh your test using the it function I wouldn't recommend it because again test Suites are great for grouping test together but you don't need one okay so just for this simple example I'll just avoid adding one I'll just say should find input by placeholder okay and then what we'll do is I'm going to go ahead and do this first let's render our component so test input field going to have the auto imported with vs code right over here so we render the input field and I'm going to go and just do expect screen get by placeholder text or whoops placeholder text and then what I'll do is I'll just do uh enter dot dot dot enter data dot dot dot and then to be in the document okay and let's go ahead and uh let's see so our test passed it was able to find it notice have I removed these three dots it's going to fail because we're using a literal string to fix that you can use a regular expression like this enter data that way you don't have to be more verbose and it's able to find that input field by the placeholder value okay there's also uh the get by display value which is literally the value of the input field itself so for example see if I do value hello and then if I go over to here well I guess I'm not rendering it right now but I'll show you what it looks like when I do render it let me render that real quick uh let me import that up top over here from not sure why my intelligence is messed up over here from components test inut field okay there we go you can see that when I render this component I have test input Fields value attribute set to hello so that is that is what's going to be displayed over here now notice how I'm not able to modify it if I try to type you can hear my keyboard in the background I'm trying to type stuff into this input field that's not being updated that's because we need to register an onchange events I'm not going to do that just for this simple example because I'm just trying to show you how we can search for the element by the value the display value so let me go into my test file and then I'll just copy this paste this and I'll say should find input by display value so we'll render the input field and then instead of using the get by placeholder text query I'll do get by display value query whoops and then this time because we have the value set to uh hello I'll just do that and then let's go ahead and see our test and you can see our test passes and if I were to add an invalid value it's going to go and fail for that specific test the second one so hopefully that makes sense now there are a bunch of other queries well actually not really there's really just like a few more there's uh get by Alt text which is for images well primarily for images you can use it for images you can use for other things too as they describe over here uh there's get by title um there is get by test ID which we already covered and we just covered get by display value and get by placeholder text so these are all of the queries I encourage you to practice the other ones that we didn't cover they're pretty straightforward and just pretty much do what we've been doing so far in the tutorial uh practice them and then verify that it was correctly passing by just placing in a value that will cause a test to fail so that way you know that you're not dealing with false positives okay so that's pretty much it with all of these different queries what we're going to do in the next part of this testing tutorial is I'm going to show you how we can actually uh test our components whenever we have more complicated situations such as when we are using react router or a context such as our user context okay so stay tuned for that now in this section of our react Testing Component with Context API testing tutorial I'm going to teach you how you can test a component that depends on the react context API so to be more specific uh remember how earlier I commented out this whole user context part so you can see that our post container component uh was wrapped inside this user context provider so if I take a look at the post container component you can see that uh it's literally just a very simple component it renders uh data that is coming from the context itself the user context specifically I'll very quickly show you what the user context looks like so it has an ID username email name and then it also has this set user data function which is actually a dispatch function which is used to update the state of the of a component that actually passes the data down to the context level and that was what was going on in our app component you can see over over here if I were to uncomment this out and let me uncomment out all the other stuff such as this user data State and the set user data function that we have and let me uncomment out uh this use fetch user hook call and let me uncomment out this use effect hook because this use effect hook uh updates the state of user data so what happens is uh all of this data right over here for user data and this set user data dispatch function they are passed to this user context provider right down over here and in case if you missed the part where we went over react context in our react tutorial go ahead and check that part out okay everything is timestamped but all that data is passed into the provider so that way any component that is wrapped inside this user context provider in this case post container will be able to consume the context and access the data if I go back to my document if I go back to my page you'll notice that right now if I refresh okay it's fetching the data once the data has been returned you you'll see that uh it is displayed to the document okay so we have post container and then all of the data right down over here is rendered and that's perfectly fine okay so what I'm going to do is I'm actually going to comment out all this stuff again CU I actually don't need this this in order to write a test for it because in our test we're actually going to be passing the data as a mock data okay so you you'll see in just a second so let me uncomment all this out because by leaving this I think it might break our tests I believe so let me actually show you if I rerun well it doesn't break the tests but it allows uh these Hooks and all these side effects to happen in the background which I don't want to happen so so I'll actually just comment out all this stuff and let me comment this whoops comment this back and then let's go down over here and comment this out okay so what we're going to do is we're going to write a test for post container but this time what we're going to do is we're going to wrap the post container inside our context and you'll see how that's going to be done for our test so what I'm going to do do is I'll go into my test folder and I'll create a new file and I'll call this post container. test. jsx okay now what I'm going to do is I'm going to import the same exact stuff that I need so I'm going to import uh I guess let's let's import all this okay and then what I'll do is let's see I guess what I want to test is I want to test the name ID email and username are in the document Okay so so we'll just do this describe um display render context values okay and we'll write a bunch of different tests to test for each to write assertions for each uh field being rendered correctly okay so here's the thing though when we render so let me first do this it should display correct username when we render our post container component right let's do that real quick so first I'll do render I'll call render and then we want to render post container like this right now okay post container itself again remember doesn't take any props all the data that is that it is referencing comes from the context itself okay now you'll actually notice that right now let me try to run this test it passes but we're not reading any assertions right now it's not throwing any errors it's not complaining about it not being wrapped inside a context because currently post container is just being rendered isolated away from everything else it's not wrapped inside a provider so when you go to try to write assertions well I mean we aren't even passing any data to the context so like how are we going to write assertions right and to even go a step further here's what I'll do uh I'll show you the snapshot I'll show you what it looks like in the default State when we're not in the context like you're not going to get an error by calling the Ed context Hook when you're outside of the context but I'll just show you what the the document looks like okay let me save so let me show you the snapshot you'll just see that it's just a bunch of it's just all the default values that were set right over here so you'll notice how zero is being displayed for the ID and then all the other things that are supposed to be rendered such as the name email username are not there it's just all empty because it's an empty string okay and I'll even be more specific let me go ahead and label this with display name ID email and then username let me save let's update the context or yeah I'm sorry update the snap shot and now you can see that we have display name empty ID zero email empty username empty okay so even though it's calling the use context hook it's just going to give you literally this value but again what we want to do is we want to actually pass values into the context provider for our post container okay so this is actually how we do this is actually a lot easier than you might expect all you you need to do is literally just get the actual context provider itself so we're going to import user context just like this and inside our render function we're just going to go ahead and do user context. provider like this and then put the post container inside the provider it's literally the exact way that we had rendered our post container wrapped inside the provider Ider now all we have to do is just pass in the values for the provider okay so you just do value and then you can pass in a username ID and then the set user data function literally it's that easy okay here's what I'll do though I'll go ahead and set up a fake user so const mock user and then we'll do ID we'll do uh let's do 101 username uh Johnny uh email Johnny gmail.com and then name Johnny okay and then we'll pass in the mock user like this and then we still need that set user data um let's see actually you know what I'll do instead of doing this I'll actually do mock user context data that way I can set the set user data property right over here so I don't have to use the spreader operator so for set user data this will just be a very basic function that does nothing and uh let me go aead and just take this and pass it as a value over here okay so now I'm going to go ahead and show you the snapshot let's update that snapshot because our UI changed you'll see that in the snapshot you can see the actual data that is in the context that we just passed being displayed so I can begin writing assertions okay so I'm going to just remove this uh I'm going to remove this part over here okay and then what I'll do is I'll just say expect screen. get by text and then we'll do let's see Johnny to be in the documents okay and then let's just update this this let's see what's going on here uh oh you know what it is let me do username colon Johnny instead there we go that passed okay um let's see I don't want to use a regular expression because it's going to go ahead and it's going to go ahead and search for it's going to match this email address as well like if I were to use uh Johnny like this it would would pick up email and our test would actually fail cuz I found multiple elements that match this regular expression so I'm not going to use that I'm just going to do username uh colon Johnny and then we can just literally write a bunch of other tests to verify the other things were correctly rendered but you know sometimes you don't even need to do that you can just literally use a snapshot test to verify that the UI is being rendered correctly then you can just look at the snapshot and just make sure that everything is rendered correctly and again snapshot tests are not useless they're very useful for situations like this where you just want to verify that basic data is being displayed so what I'll do is I will leave this alone uh and then I'll just go ahead and write another snapshot test I'll just say it should render all I'll just say it should match snapshot because it is the it is redundant for me to literally copy this test multiple times and just verify every single uh every single uh data email and name like it is redundant when I can just look at the snapshot and verify that it is correct so I will go ahead and I'll move this up top over here so I can reference it again and then I'll render my data and then I'll go ahead I'll render my component and then go ahead and get the container and do expect container to match snapshot okay and then let's update everything okay there we go I can just look at my Snapshot verify that everything's good and then we are good to go and again if I were to make changes to my post container component my Snapshot would fail and then we have to determine whether or not it was supposed to fail in other words is the UI change supposed to happen and if it's not then we have to modify UI to make sure we are not changing it for no good reason okay all right so while This Test shows you how to actually verify data in the context is stored properly and you can see it from the snapshot the question is how do we actually interact with our component where we can actually modify the data in the context right because actually in the post container component we actually did render this post content component as well and then we also rendered the post content buttons component component and what this post content buttons component did was it actually updated the uh the name value in the context so I'll actually just rerender uh post content again so let me render post content and I need to import that again so let me import post content from post contents okay and then uh let's see we're not using data anymore so I'm just going to remove this prop and as you can see post content renders post content buttons okay so let me just show you what was supposed to happen Okay let me refresh the page I do need to make sure post container is runed again so I do need to uncomment all this out and I'm just going to uncomment all this out for now because it's it's not breaking our other tests so I'll just leave it like that for now okay and all all of our tests pass no problem well the the snapshot needs to be updated because we made a change to our user interface okay so all of our tests are passing that's great okay you can ignore the warnings for now okay wonderful so our tests are good so this was this is what was supposed to happen Okay so right over here in the post content buttons let me actually uh let me do this I should have done this earlier let me change this to an H3 tag and then let me change this to an H3 tag as well that way it's easier for me to distinguish everything okay so right now you can see that when I refresh the page you can see that I have my post content component and then inside the post content component I have post content buttons so what actually happens is when I click on the click me button you'll see that the cont context display name value was updated notice how it says updated display name okay obviously not the most useful update but I just did this as a very easy example to show you how this worked okay so what I will do is I will actually add uh another input field and I'll actually do this um I'll add some State I'll call this value set value and I'm going to actually make it Dynamic so I'm not just hardcoding some text that is meaningless so basically what I'll do is I'll do this I'll bind the value to my state variable value and then I'll register the onchange event listener and then whenever the onchange event is invoked we'll call set value and pass e. target. value and then what I'll do is whenever I click on click me or I'll actually rename this button uh updates or save display name okay and then I'll uh set this to be value just like that okay and then now basically whenever I type something into this text I'll say Johnny and if I click save display name whatever I type inside this input field is what will be uh reflected on this display name or over here if I click if I type Johnny 123 and click save or save display name it's going to go ahead and display Johnny 123 that that is how we're going to test updating the context now you're wondering well in our post container component for this set user data function we just passed in this you know this empty function that does nothing so even if we were to call set user data it's not going to actually update the actual data in the context so here here's the thing we cannot test the actual update of the context from the post container itself we need to go one step above and we need to basically go to the layer where we are actually rendering the uh provider with the component itself which in this situation that's our app component because the app component has the US state call which is going to give us the dispatch function that we can actually call to update the state user data which will then in turn update our context for us okay now the other problem here is that the user data is currently updated whenever the the API call is done use fetch user so what I'm going to do is this I'm going to go ahead and just comment out this use effect hook and I'll comment out this use fetch user API call I'm going to leave this use State hook alone cuz we we will need this and the only difference is uh I guess what I'll do is I can actually just pass in a hardcoded value so I just do ID uh 7,000 username uh Johnny display or not display name uh email Johnny gmail.com and then name Johnny Johnny the developer how about that so now what I want to do is I actually want to write my tests on the app component instead of the post container component itself because obviously I can't just call the UST State hook inside my describe uh function right over here that's not going to make any sense and this set user data function is a mock function so it's not going to do anything even when it's invoked okay so we need to do it from the component that actually defines the state that is passed into the context provider in our case it is the app component itself for you it might be something else okay so just keep in mind that whichever component actually defines the state so in this case it's app then we need to make sure that we are rendering the app component and then writing our unit tests okay in this case it's more so of an integration test rather than unit test because you know a unit test you're actually testing an isolated component just one individual component and an integration test you're actually combining multiple components multiple features together and testing them as a whole okay so what I'm going to do now is this let me make sure that nothing is failing I do need to update some snapshots okay so let me just make sure all my tests are passing before we continue and yes everything's passing so that's good uh okay so now what I'll do is this I'm going to go into my app. test. jsx file and we're going to go ahead and go down over here and set up another test Suite because right now this test is completely different than all the other tests that we wrote previously okay so this time we're going to describe updating user context okay and again like I said this is just a very basic example we're only updating one piece of information which is the display name but you might have a more complicated form that allows you to update different fields such as the ID email or username or all or all three so what I'll do is this I'll just do I'll just set up one test it should update display name okay and now again if we look at our components okay we look at our if we if we look at component we're dealing with an input field right so right off the bat I need to make sure that my input field is is actually queriable like I can actually look for it so again earlier I mentioned something where I said that writing tests require you to also set it up to be successful right if you purposely go out of your way to set up your components and your elements to be difficult and impossible to test you're going to have a hard time writing a meaningful test and writing a test that can actually you know search for your elements and perform operations on it and I'll give you an example okay right over here in my post content buttons component which I know it says post content buttons but I did add an input field we we'll just go with it for now so this input field right over here I need to be able to actually get this input field in my test right but how do I get it because right now in the app component I have this other input field over here so there's going to be a conflict between knowing which input field to query 4 and especially this input field doesn't have any other meaningful data like it doesn't have placeholder text it doesn't have a default value set it doesn't have an ARA label okay so how do I grab this input field okay so again this is what I mean you have to set up your components for Success right what I can do is is I can either give this input field a label which is what I would prefer to do I think every input field should have a label that's just me uh you can also set an ARA label so you can query the label by the by the uh name or you can get it by rooll and set the uh value of the AAL label to the name however I'll just go ahead and use a label so we'll do HTML 4 and then we'll go ahead and just do this for the ID of this input field I'll call it update this display name and then pass in that as well for the html4 attribute and then we'll call this update display name I I'll call it update name just to be more just to be more simple okay update name and let's refresh page there we go that's our label right over here okay so again these are things that you want to always make sure you're considering and like I said setting up your components for success okay and is there a reason why your input doesn't have a label associated with it well I mean usually for good practice you should associate your input Fields with a label because it makes accessible accessibility for it a lot easier right like I can just click on this label and I can easily start typing stuff into the text box okay you don't need a label but it does make life a lot easier when you have one okay anyways let's go ahead and continue so what I'm going to do now is everything that we've been doing before so we do know how to search for an input field by its label text so we're going to go ahead and first render the app component so render app okay now this time when we render the app component keep in mind that I don't need to actually wrap the app component inside the provider because the app component actually renders the components that are wrapped within the provider okay before in my post container component I had to wrap the render of the post container inside the user context provider but in the app component we are already rendering this post container inside the provider so we don't need to do it anymore and all that all of the values that are passed in are already defined right over here okay if you wanted to make this more Dynamic what you could do is you can actually just pass you can actually allow the app component to take the user data as a prop and then just set that as the initial value kind of like how we did for users data okay but I think for this example we probably don't need to do that so here's what I'll do I'm going to render the app and let's just make sure uh let's see what's going on with our test can I read properties of undefined map uh let's see what's going on here I think it's a snapshot issue okay so one of them was a snapshot issue should update display name uh canot read properties of undefined oh yeah that's because we didn't pass in the users data forgot about that let's go ahead and do that we'll just pass an empty array because that has to do with uh all of this stuff over here we don't really care about that because we're not testing for that so we can just ignore it and this is the nice thing about writing tests is because you don't need to always passing the same exact props for every single thing that you're rendering okay so okay our tests are all passing but let's actually write an assertion for this test because we didn't write any assertions yet so let's go ahead and do this uh we'll [Music] do uh screen get by label text update Name colon so that's going to Target uh this label right over here and give us this input field and then we're going to use we're going to use this input field and we're going to fire an event so we're going to use the user event. type method we're going to paste in that element and then we're going to type uh we'll do let's see you can literally type whatever you want I guess I'll just do um John Jonathan the dev how about that then we need to make sure we await this user event. type call because it's asynchronous it returns a promise let's add the asyn keyword in front of this call back and await this call and then we want to make sure we click on the save display name button so that will require us to buy another event so we'll do a user event doclick and then we need the actual HTML element which is the button to click on so screen get by roll button and then the name of the button is literally just save display name okay and then this is asynchronous so we await the call and then now we want to write a test or you want to write an assertion to verify that uh let's do this verify that uh display name colon Jonathan the dev is in the document okay and uh I'll also do this um let's do this uh let's see screen get by text display name Jonathan the dev okay and let's go ahead and run our test and let's see what happens so let's run it again and you can see that everything passes and nothing fails so that's wonderful okay and if I want to make sure that's oh wait actually I didn't even do anything sorry about that got a little bit too ahead of myself we actually need to write an assertion expect well I mean you know like I said if if this was actually supposed to fail like if it didn't find the uh the text in the document this get by query would fail right remember get by will throw an error if I cannot find it in the document so the fact that it didn't throw an error is good but still let me actually fix this real quick by doing expect screen. getet by text and then to be in the document let's just make sure nothing fails okay that's good and then I can just kind of like mess this up a little bit make sure that we don't have any false positives and you can see that it fails now because you cannot find this text in the document and then you can see right of here the actual display name is Jonathan the dev okay so hopefully this shows you how you can test updating the context okay all right so now in this section of our react testing tutorial I'm going to Using Mock Service Worker to Mock API Requests teach you how we can actually simulate Network calls for our components that need them so for example in our app component we were calling this use fetch user hook a custom hook that we created that makes an API call to this Json placeholder uh users endpoint and it gave us back a user now obviously we're sick and tired of having to comment this out but like I said in a unit test and in an integration test you don't actually want to call any real API you don't want to actually make a real API call okay because again your tests are supposed to be fast they're supposed to give you instant feedback whenever you actually want want to actually call a real API or if your API is calling a real database you do that in an endtoend test okay we're not writing end to end tests right now we're writing just basic unit tests and integration tests okay so in a situation like this you want to simulate Network calls you don't want to just get rid of them because your components rely on them you want to simulate them mock the response so that way your component can actually use that data that is returned from the quote unquote mocked API call okay so I'm going to show you how to do that we're going to need to use a tool called mock service worker now I actually did a tutorial about this probably like a year ago where I taught uh you all how to or I taught people how to use mock service worker but um I'm just going to show you how to set it up again because there's no point for me to just tell you to reference that video when you're already watching this video okay so basically mock service worker can be used in two different ways one you can use it for a react application to Mock and well intercept and mock responses okay so for example let's say you want to build your react application but you don't want to worry about setting up an API just yet because you're just probably not ready for it yet and maybe you're not a back in Dev and you only want to focus on the front end side of things so you can use a mock service worker that will basically run in the background of your react application and then whenever you are making requests using let's say the fetch API or axios what mock service worker will do is it'll basically just intercept those requests and then it will basically mock the response and so it'll basically seem as if you're calling the API but in reality the mock service worker is pretty much like taking over that request and giving you the mock response that you set up yourself so that's one way they can use mock service worker the other way they can use mock service worker is on the server side the node.js integration well there's also react native as well we're not going to talk about that but you can see over here on the sidebar there's the browse integration which is what I just described okay and they show you an example right over here we're not using the mock service worker for the browser okay because we're actually making real API calls you can if you want to but you don't have to okay especially if you already have a real API endpoint for development purposes that you can call for Local Host now if you go to the node Jace integration you can see that this node ja integration part is useful whenever you want to use a mock service worker for node.js processes okay so in a situation where we are actually writing tests this is the perfect example to use a node.js integration with the mock service worker because what we can do is we can actually write our tests and then we can set up a fake server and then set up a bunch of fake handlers that will give us back our mock response cuz remember that vest is actually a no JS process okay it's not running although it is actually you know simulating the JS Dom environment right like it's rendering the data to the document it still is a nodejs process at the end of the day okay so when you set up your mock service worker you want to make sure that you setting up you're setting it up for the nodejs integration so the first thing that we're going to do is install mock service worker so in the terminal just type npmi hyen D mssw latest okay this will just install the latest version of mock service worker MSW being the package name okay now what we're going to do is I'm going to go inside my source folder I'll create a new folder called uncore Mox and uh let's see I'll actually create another folder called mssw and I'll create a new file and I'll just call this I guess server. J yes and then what we're going to do is import the setup server function from MSW and notice how there's node and then there's browser there's also native as well which I believe that's for react native but we want it for node okay because we want to use this in the nodejs environment so we're going to import this setup server function and then what I'm going to do is I'm going to export a variable called server and we're going to call setup server and we need to pass our handlers okay so it's an array of handlers but we want to actually use the spreader operator on it okay so currently we don't have any handlers and you're probably wondering well what are handlers well handlers refer to the request handlers so that's basically how you're going to set up your API routes for this mock server so basically the way it works is you set up these fake endpoints that the server is going to quote unquote l listen to so whenever your react components are making a call that match the Handler mock service worker will B will basically match that and then give you back the mock response that's how it works and I'll show you how to set up handlers so what I'll do is I'll create another file and I'll call this handlers. JS because I like to keep it separate and then all I'm going to do is just export a variable called handlers which is going to be an array and then we want to make sure we import this HTTP from mssw and this is actually a uh a constant that has a bunch of methods that we can call it looks like the expressjs instance the app instance itself so for example I can do HTTP Dot and then the method that I want to replicate that I want to mock so what I can do is http.get and then I can go ahead and simulate uh the routes so in this case what we want to do is we want to actually provide the actual route that our component is calling okay so in this situation right over here if I go to the hook uh use fetch user you can see that the hook itself is calling this endpoint with a dynamic user ID okay now typically whenever you use a mock service worker it's it's good good to use the mock service worker for the browser as well as the as well as for your test as well so for for good consistency but you're not always going to get that case cuz for example we're using an actual real API endpoint to get the data so in the test I don't want to actually replace that API endpoint but I don't want to actually call that endpoint as well in my test so I can just paste in this whole URL I can also just paste in the actual ID now we obviously don't want to hardcode the user ID because it's Dynamic so what you can do is you can actually use a wild card by just adding the asterisk instead of the hard-coded ID so any API requests made to this endpoint during our tests and with the dynamic user ID will be resolved right over here so the second argument that we need to pass into this http.get call is the resolver function and it takes in one argument and the argument itself actually gives you a lot of different properties so I'll show you so uh this is what it's going to look like resolver oops resolver just like that okay and uh I can actually just reference this right over here and you can see that there are a bunch of properties we have cookies prams request and request ID so um for example the request property gives you an object that's it's identical to an actual request object on the server side like for example if you're using expressjs it looks similar to this right so if the request itself had a form data or if it had a request body you can get it from this request object if you wanted to get uh request parameters or the cookies you can get it from the resolver okay but uh what we want to do is we actually want to return a response okay we want to return a response and this time since we are mocking this API call we can return literally anything we want we don't have to return the actual API endpoint returns but in order to be consistent with our application we should make sure that we return the bare minimum that we are using so in our case we're using uh let's see the ID username email and name field so we should make sure that our mock response includes all of those fields for that endpoint so what I'm going to do is this I'm going to return and we're going to ref reference the response interface like this this is part of the actual uh this is built into JavaScript then we're going to call it Json okay and then what I'm going to do is I'm going to return so keep in mind that this API npoint it allows you to fetch the user by the ID right so let me just show you real quick so you can see that I can fetch the user by ID one so we should make sure we should also return the same ID that we are fetching the user bu so what we can do is first I'll actually just destructure the pams property from the resolver object because I don't need the entire resolver object so for the ID I'll just set it to prams doid because that ID is a route parameter and then we can literally just send back whatever it is that we want okay so uh let's see I'm going to send back the username we'll just do uh Josh name Josh and then email Josh josh.com something like this right again just a very plain simple example now let's go back to our setup server and what we want to do is first let's import handlers from the handlers file that we just created and then we want to make sure we pass in handlers but use the spreader operator on it okay and that's how we set up our mock server okay that's literally it and again if you want to add more handlers down the road you can so for example if you want to mock post requests you can do that if you want to mock put requests you can do that if you want to mock more get requests you can change the endpoint right and keep in mind that during your tests you can also override the handlers which I'll show you how to do later on so in order for us to enable aable our mock service worker for our tests because we only want to use this for our tests again you can use it for your actual react app if you want but that involves a different setup so we're not going to do that we want to enable it for our tests so what we want to do is we want to go to our test or our setup tests file right over here okay and then what we want to do is first we want to import this before all hook okay and this before for all hook will be called the Callback function of it will be invoked before all of the tests and what we want to do inside this before all hook the Callback is we want to start up our server so our mock service worker server so we're going to go ahead and first import the server that we created from the uh server.js file right over here this is what we're importing into the setup test file and then we're going to reference server. listen just like this okay then what we want to do is after each after each uh test what we're going to do is we're going to go ahead and call server. reset handlers and then what we're going to do is after all the tests so let's go ahead and import the after all hook we're going to go ahead and just call server. close because we obviously don't want it open and this will avoid memory leaks and stops requests in general okay all right so let's go ahead and try running our tests let's just make sure nothing breaks with what we're doing currently okay all right so everything is working just fine but let's actually write some tests that use the mock service worker CU right now we're not really doing anything with this we just you know called server. listen big deal we're not doing anything with it so now let's actually go ahead and write some tests that do that okay so how do we actually write a test to successfully use our mock server well first we need an actual component that is making an actual API call that is matching our handlers so remember what I said earlier we need an actual API call a get request specifically because that's the one that we currently set up to this endpoint with the user ID okay so we already have that this app component currently calls the use fetch user or it doesn't we need to uncomment it so let's uncomment it okay so we are invoking this use fetch user hook and all it's literally doing is making this uh call right over here this callback function okay and then it makes an API call to this same exact endpoint that we are mocking okay and then it gives us the data back right over here okay so earlier I did hardcode my data right over here I hardcoded the user data but we're not going to do that anymore okay what I'm going to do is I'm going to actually remove all of this and then what I'm going to do is I'm going to uncomment this use effect hook that I had before that I originally commented out in the start of this react testing tutorial and just to explain what's going on basically what we're doing is we are checking to see if we're not loading because remember loading is a Boolean value that gives us the status if we're loading or not so we want to make sure we're not loading we want to make sure there's no errors so if uh error is a if uh if no error in this case it's checking to see if error is uh falsy so if it's not falsy then this whole thing will be true and then if user is defined okay so if this whole condition statement is truy then that means we're going to go ahead and update set user data we're going to call set user data to update the state of user data and that is going to be the data that is given from the actual API server itself but remember we're using the mock server okay and we have all all of these variables as our inside our dependency array okay so now we're no longer using well we're again we're still using mock data because we're mocking it with the mock service worker don't get me wrong we're still using mock data okay but at least this time we can actually have our API call in the component without needing to worry about it hitting the real server and we can still mock the data as needed okay so now uh our context our user context is going to have our user data state which is going to be the data that is coming from the mock server mock service worker so let me actually run all the tests again and uh let's just see what happens uh it's hard to kind of tell right off the bat so we want to make sure that the mock service worker is in fact being used and right now let me see if there's any way for us to tell cuz typically what will happen is at least in the browser side it will tell you that certain requests are being intercepted but right now it's not telling us anything okay so I think the best thing that we could do is this why don't we do this uh why don't I write an assertion uh let's see because right over here we're just updating the user context okay uh why don't I write an assertion on the app component asserting that the username uh Josh or maybe email Josh josh.com is being rendered okay so let's see what does that look like uh email okay yeah let's do that so why don't I do that real quick uh let's do this describe um rendering context data I guess so what we're going to do is we're going to say it should render correct email okay and then what I'm going to do is I'm going to render the app and then keep in mind that this time our data is not going to appear instantly it's coming directly from the mock service worker though we could actually delay it but I mean again we're using the mock service worker so it's not actually calling the real API so I think it should return almost instantly or or at least uh before the default timeout is reached okay so let's actually see what happens when I do expect screen get by text and then email Josh josh.com let's actually see if the service worker is working okay so right now it's not and you can see that everything is currently empty so it seems like it is taking some time for the data to display okay and that's okay so what we need to do is this instead of actually just using get by text we'll use find by text okay so expect and then we'll do await screen find by text because remember this actually uh will search up to 1 second for the element itself and again even though we might be using the mock service worker doesn't necessarily mean that the data will appear instantly so let's actually see what happens okay so 1 second has passed and let's see seems like the data has not appeared so this tells me that perhaps the service worker may not be actually being hit and one thing that I can do is I can actually just set a timeout so let me pass a timeout of 10 seconds or yep 10,000 milliseconds and let's see if this gives us any more information okay so now our test actually passes and it says okay it's able to actually find the text by email so I guess it takes longer than 1 second for it to appear let me let me just kind of see if I can uh pass in an invalid email okay so I pass in an invalid email it's going to take up to 10 seconds because we set that right over here to find this element by the text and it's not going to find it because as you can see now the data is actually being displayed okay you can see right over here that we have yep so it seems like the actual data from the mock service worker isn't fact being used okay because you can see username Josh name Josh and then Josh josh.com are all being used okay if I were to actually remove this Handler if I were to remove the Handler and run the test again you can see what happens it's going to take up to 10 seconds to search for the text right over here and it fails but if you look at the actual data all of this data is actually coming from the real API itself don't believe me well just take a look at what is displaying on our actual component okay right over here and uh if I open the dev tools you'll see that the network tab right over here this is what it is giving back the name username all that stuff is literally right over here so this proves that when I remove that Handler the server the mock service worker is not able to it doesn't match any of the handlers at all okay so it just lets the real API get called but if I were to set up a Handler where I match the same exact URL then the mock service worker will intercept that request made and we can change the return value so I hope that this makes sense now one thing that I do want to do is I want to avoid modifying the timeout so one thing that you could do is this you can actually do a weight and then use this weight four method that is imported from the react package it didn't Auto Import for me but I'm going to I'm going to import up top over here so you can use this wait for method and this literally will allow you to pass a call back to wait for an element to appear on the screen so this is a good this is good to use it with the uh screen. find by text call okay so we can literally just do async and then uh await screen. find by text and then uh what I can do is I can actually remove this async keyword from this callback function actually I still need it sorry uh but instead what I want to do this time is this I want to instead I want to do this instead expect to be in the document and we're going to do it we're going to just put the actual real value that will be in the document not the real value the mocked value okay so let's run the test again hopefully it passes hopefully wait for will work let's see what's going on here did it time out let me see um yeah it timed out I wonder if yeah I guess it takes too long I wonder if there's a way to speed this up so I tried to do some digging and I don't think there's a way to speed up the response from the mock service worker um so what I'm going to do instead cuz I don't want to actually set the time out manually every single time cuz right now right if I use a wait wait for I can pass in an object to set the timeout to be 5,000 milliseconds and then the test will actually pass right over here you can see that it takes up to I guess 3 seconds for the response to come back so the best thing to do when you're dealing with with a lot of asynchronous calls to like an API for example is just uh set a global timeout and one thing that you can do so for example I don't have to manually go to every single test and set the time up to 5,000 milliseconds I can go into my setup test file and uh there's a function called configure that you can import from the testing Library SL react package and then all you need to do is literally just call this function and then you can just set async UIL timeout over here and you can just set it to whatever you want so I'll just set it to I'll set it to 4,000 for now you can set it to whatever you think is appropriate for your application needs okay so I don't have to worry about setting this extra option anymore and let's go ahead and rerun everything because we're making changes to the setup to set set up test file and now I can see that everything passes so yes it does take some time for the API to uh give back the response at least the mock API okay um okay so hopefully this makes sense now I'm going to show you an example where we can override the default handlers because right now uh we have these handlers set up over here and these are kind of like Global handlers right like they're kind of like just default handlers that any test can use but sometimes you might want to use a different Handler you may want to return a different response you may want to override the uh the behavior of said endpoint right so for example you might want this endpoint to be mocked in a way to return a 403 to handle uh that status code so that way you can display a conditional message to the user saying that oh yeah you're not authenticated please log in these are just examples right so I'll show you how you can override the handlers in real time in the actual event of the of the test going on so this is how you can do this okay right now I'm writing an assertion to the document uh that this text email colon space Josh josh.com is in the documents which it does appear after about uh 2900 milliseconds so what I'm going to do now is inside this test I can actually reference the server the mock server right over here okay and then let me first import it up top over here so let's import server from then we have to go into MOX mssw server just like that okay then what I can do uh let's go down over here okay then what I can do is inside right before I render the app I can reference server and then what I can do is I can go ahead and call the use method okay server. use and then I can just pass in any amount of handlers I want that I need okay so let me just copy this and let's see I do also need to make sure I import uh the http constant from mssw yep there we go let's go back down over here and then I can literally add as many handlers as I want in my like I said my app component only makes one API call so I only really need to just passing one okay all right so now I can go ahead and change the behavior of the of the resolver right so I can go ahead and override the response. Json so for example I can return a username of Joshua uh for the name I'll do Joshua and then for the email let's do Joshua yahoo.com okay and now watch what happens with my test you're going to see that my test should fail in fact it will fail you can see now it says timed out okay because it can't find that specific text where the email colon Josh jos.com is there okay and if you look over here the actual text is Joshua yahoo.com okay so now you can clearly see that we are manually overriding our Handler during the runtime of our test which sometimes you might need to do because not all the time you want to use the default handlers that you set globally when you call the setup server function okay so we can go ahead and modify our test and I'll just say uh email Joshua yahoo.com that's the text that we're trying to search for and now our test is going to pass after uh 2,000 milliseconds okay so I hope that this shows you how you can actually use the mock service worker to literally intercept these requests and then return a mocked version of that request again you can return anything you want so another example is I can return an error if I wanted to so what I can do is this instead of using uh response let me actually use HTTP response instead um let's import that from the mock service worker package and we'll go down over here and I'll return HTTP response dot uh error like this and uh let's just see what happens so we're responding with a network error and if we look in our test you can see obviously it's going to fail do it log anything don't think it does that's okay but it's failing so it's not able to get the dat but again like I said our application currently we're not handling errors which we should but uh you can basically write like a custom error message page so like if the data was failed to load from the API you can just say fail to fetch something like that and then you could test for that so again I'm just trying to be creative and show you all different ways to return different things so I hope that this makes sense and hopefully gives you some create ity on how to test different scenarios now one more thing that I do want to show you is you can also delay requests as well so I'm going to go ahead and import this delay function from mock service worker and what I'll do is right over here yep right over here uh first you need to make sure that you're inside an asynchronous function so notice how I guess I added this off camera but you want to make sure you add the async keyword for your resolver function right over here like that so async and then what you want to do is you want to call the delay function that we just imported and remember this is asynchronous so you need to await this call it returns a promise and then you just pass in the amount of milliseconds you want to delay the request by so you can delay it by 2,000 and then basically it will just literally just delay The Call by 2,000 Mill second so to show you if I run npm run test I also did update my uh let's see where was it I updated the async util timeout property to 5,000 just to let you all know and then now you can see that it takes about 4,000 milliseconds for our app test to finish specifically for this test uh I wanted to show the actual test itself let me see if I can get it to display because normally this test right over here takes about two seconds but now it's taking I guess two seconds plus another two seconds okay and notice how if I were to add uh let's say if I add one more second I believe this will probably fail because it'll go over 5,000 milliseconds because it times out at 5,000 yep there you go you can see that it took way too long and it timed out so the API call failed so this is helpful if you need to delay requests perhaps maybe on your frontend and you have some kind of logic where you are going to cancel the request if after let's say 15 seconds a response was not received from the API call itself so then you want to cancel it and then display some kind of custom message through the user and then you want to write a test for that so this delay function is helpful for that case so I'll go and just I'll just remove this cuz I don't really need it I just wanted to show you all how that worked now in this section of our react testing tutorial I wanted to show you a couple of examples on how we can write some tests with our react router so let's say for example we want navigation in our website and we want to make sure that our navigation is working correctly so in other words I want to verify that when I go to the base URL that this app component and all of its contents are rendered when I go to the blog post page all the contents of the blog posts page component are also rendered as well and then if I go to the users page so this users pathway over here then all of the content of the users page is rendered so it's also an important thing to know how to test your application when you do in fact use react router so I might to just cover some examples and show you so this will require a little bit of a setup process but it's not that complicated don't worry and I will also warn you that we do have a navigation bar right over here but the moment that I uncomment this app out all of the current tests in our app. test. jsx file it will actually throw an error the reason why is because currently the app component itself is trying to use these link components and in order for you to use these link components you need to be inside a router provider context which currently by rendering app by itself it's not going to give us that router provider context so what we need to do is we actually need to set up a custom render that will actually render the router provider for us and then it'll also set up a temporary or not temporary but a memory router and then that's how we can actually render all of the correct routes with the corresponding components so I'll show you what I mean so what I'm going to do is inside my main. jsx file I'm going to copy this array and I'm going to cut it and I'm going to go into the utils file or utils folder and I'll create a file called uh let's see constant. jsx and then what I'll do is I'll export this routes variable and it'll just be my array right over here and then now I need to just make sure I import all of the necessary Imports I'm going to import app import the blog post page component and the users page component right over here one thing that I do also want to stress is that since you are dealing with jsx inside this file you need to make sure that this is a jsx file and not ajs file extension otherwise you will get some errors when you're trying to run your tests or any file that will import this constant. jsx file if you don't have that jsx extension and you're trying to use jsx it's going to give you some weird issues so just make sure you have have this jsx extension okay so now I'm going to go into my uh main. jsx file and import that routes array that I just created so this makes it more reusable so we're going to go ahead and import that from constants there we go so we're done with that and I can just remove all three of these Imports we no longer need them so what I'm going to do now is in I guess uh let's see inside my tests file my folder I can go ahead and create a utils folder inside the test folder CU we will need some utilities for our tests but most importantly I'm going to create a file called I guess helpers.com render so typically they call this uh render with router and what we want to do is basically just render oh well there's two things that we need to do first we need to create a memory router so we're going to need to import this create memory router function so let me do that real quick so import create memory router from and that comes from react router Dom and then we basically want to take that rout array that we just moved into the constant file right over here and then just paste it right over here we do need to import it of course so let's import that and then we need to pass in a second argument which is the options and then this is where you want to set the initial entries so initial entries is an array and it basically just allows you to populate the history stack so for example I can do uh base URL users blog posts things like this okay and you can also set this initial index and then for example if you want the initial uh entry the initial path to be uh this base URL you can just do the index of that so that's zero if you want it to be users you can just set that to one uh personally what I like to do is I like to actually pass these in as options so for example you can uh have your render with router function take in an object that has initial entries set to an MD array or initial index set to zero like this okay and then what you can do is you can just assign it to this object right over here and it would work fine so the next thing that we want to do is we want to import the render function from the testing Library react package and then all we're going to do is just return render and then you want to render the react node so in this case the only thing that we're going to render is the router provider and then set the router prop to the memory router we just created so this will basically just do what is uh happening inside our entry point over here so you can see that we're rendering the router provider and then uh the router prop gets passed and then pretty much all of these routes that we have configured will end up getting conf configured with the correct path and then the correct component that relates to that path itself so the same thing will end up happening when we render this router provider it'll render all of the entries that we have set up which is just going to reuse this routes array right over here and then we should be able to just access each path the only thing I don't like about this is that it doesn't allow you to get immediate access to the individual component so when you're trying to test your app component with a router you can't pass in custom props like this but then again though um in a realistic application you're not going to actually pass in hardcoded data as props to this you know to this app page itself we need to eventually update this to have it fetch the data from an API but for now we can leave it alone because that's not really an important thing to fix right now so now I'm going to go ahead and show you what happens when I do this so I'm going to just leave the app. test. jsx file alone for now and I'll just go ahead and create a test I'll just call this app with router. test. jsx okay and then all I'm going to do is just import the custom render this render with router file and then we need to import all the other uh functions from vest and then we also want to import screen and wait for well we don't really need wait for I'll import that if I need it and then I'll remove the render import because we're using render with router okay so now what I'll do is I'll also use user event as well because we do need to click on stuff okay so I'm going to go ahead and write a simple test I'm not going to use any test Suite just because I want to speed things up a little bit so I'll just go ahead and say it should um it should render Navar and click actually I'll do this it should click on users link and navigate to users route okay bit of a long test name but that's okay for now so what I want to do is I want to call render with router just like this and then you can set the initial entries so what I'll do is I'll set it to be just this base URL for now and then I'm not going to do anything for the initial index cuz by default we have it set to zero so that's okay so now remember that by setting the base URL this base path it's going to go ahead and render the app component for us okay cuz that's how we have our routes set up right over here so the first thing that we are going to see or not we but like the test Runner will actually be able to interact with are all of the elements that are inside this app component which is fine because we're going to go ahead and click on the Navar links right over here I'm going to uncomment this out for now okay I'm going to go ahead and click on this users link and then I'm going to write an assertion that will allow me to verify that the users dashboard text is in the document okay so let's go ahead and do this so we're going to render with the router we're going to set the base we're going to set the initial entry to be the base URL and then what I'll do is I'll write an assertion to verify that the user link is in the document so the way that we can do this is we can use screen . getet by roll and then the RO is going to be link and then the name will be users like this okay and then I'll just say to be in the documents uh though I probably don't even need to write this assertion because like I said get by roll will fail if it cannot find this so I'll actually just immediately just fire the event on the element so I'll do await user event. click so I'll just click on the link immediately and then what I'll do is I'll write an assertion and I'll go ahead and say okay uh expect screen get by text and remember that when we're on the users uh route I'll show you when we're on the users route all it shows is welcome to users dashboard okay so all I'm going to do is just hardcode the text welcome to users dashboard just like this and then we'll use the 2B in the document matcher and let's go ahead and run this test and see if it works so in my terminal I'll go ahead and just do npm run test app with router I only want to run this test file for now and right now it's complaining it's saying expression expected so I was running into this issue for like the past hour so the reason why this is happening it has to do with our uh our our name the file extension uh and I'll show you real quick where this issue is coming from so I believe it's right over here yep this should be named helpers jsx the reason why is because we are using this route we're importing this routes array and it's using uh an object with jsx so that's the reason why and if I save now I believe this should fix the error uh let's see okay so it does fix the error but now it's going to error out with a different thing and it's saying that cannot read properties of of undefined reading path name so uh let me see what's going on with this now it's complaining about this part right over here create memory router initial entries oh you know what it is I think I may have messed this part up I need to actually pass an object and set initial entries to this that should fix it okay there we go so now you can see that the test passes sorry about that okay so our test passes now notice how if I were to just change one little thing in the get by text call and now errors out and you can see that this verifies that we are on the user route because this entire component this users page component is rendering with the H1 element with this welcome to users dashboard text okay so hopefully that makes sense and of course you can write a bunch of other uh stuff if you want now currently the users page does not have the actual um navigation bar but the blog post page does so what I can do is I can write some tests to verify that we're navigating successfully from the base path to the blog post path and then back to the P base path so why do I do this I'll go ahead and copy this whole thing and I'll just change up the name of the test and I'll go in and name the test this uh it should navigate to blog posts and back to base path okay so the initial entries will set it to the base path so this time what we'll do is we'll change uh the users to I believe it's going to be blogs instead that's the name of the link so we're going to search for this link right over here blogs and we're going to click on it and then now we're going to go ahead and write an assertion so instead of Welcome to users dashboard it'll just be welcome to blog posts page so I'll just hardcode that string right over here let's go ahead and just run the test again make sure that part worked so it did okay and these console logs I believe are coming from the blog post page it's logging the state. posts or the state object right over here and the window. history. state I just remove this because we don't need to have that okay so we're going to go ahead and write this assertion which we just did to verify that we are in fact on the blog post page and then what I'll do is I'll search for the home link click on it and then verify that the welcome to blog posts page text is no longer in a document and that should be pretty easy based off of what we've learned in this whole testing tutorial so what I'll do is I'll copy this part await user event. Click screen. getet by roll or still going to have the link roll but this time the name of it is going to be home so we're trying to look for this home link right over here and then we're going to click on it when we click on it we're going to go ahead and verify that the welcome to blog posts page is no longer in the document so the way that we can do that is using the query by text function and then instead of checking to see if the element is in the document we just verify that this is null so remember that query by text will return null if it cannot find the element in the document based off of this match okay so it is going to be null and let's verify that by looking at our test so let's run the test and you can see that it does pass and what I could do is I can just go ahead and say not to be null and see if that fails and it will fail because it is in fact null okay so yeah again like I said there are many ways they can customize this um and like I said this render with router you can always customize this to your need like I said earlier I don't like the way that this is set up but this is what I could find on stack Overflow as a good solution because the reason why I don't like this because you don't have full control over these um these uh components but like I said it doesn't really matter because ideally in the actual real application I'm not actually going to pass this hard coded data and in fact um I would actually just remove this entirely this user data's array this user's data array and then what I would do is inside the app component I can fetch a list of users the same way that I'm fetching an individual user and then when it comes to testing I can actually just use the mock service worker which I showed you in the previous section of this testing tutorial how to mock the response back from the API and then I can just basically store that data in some State the same way that I'm doing it for the individual user itself and instead of referencing this uh users right over here which is just the data passed from this prop which is hardcoded I would just reference the fetched data okay but like I said you can always customize this you can find a bunch of different instances on this render with router function this isn't something that I came up with myself if you go to the react testing Library docs they actually have a page where it teaches you how how to actually create a custom render and this is just one variation with it that I believe is as basic as possible but I encourage you to customize it to fit your needs so I believe that's pretty much it when it comes to testing with react router and that's going to be it with just testing in general so I hope you all enjoyed this part of the tutorial and I hope you enjoyed the entire tutorial in general if you've watched the entire thing so I'll see you all in my next episode peace out