Learn React 18: The Complete React Developer Course | FREE COURSE

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] so you want to learn react and naturally so it is the most popular framework for building user interfaces and i get it you want to learn react but you're not really sure where to start because after all it is drastically different than traditional client-side development with just plain old javascript and libraries like jquery but don't worry i've got you covered hi there my name is jeremy mcpeek and i invite you to spend just a few hours with me so that i can teach you all of the fundamentals that you need to know about react we'll start at the very beginning with just the react javascript library and plain old javascript you know just to get your feet wet but then we'll wade into the water with the basics of the react tool chain and i'll teach you all of the rules of jsx and how we use it with javascript to build components then i'll teach you about props you can kind of think of them as function parameters and you'll learn how to validate and provide default values for them you'll learn how to handle dom events and even create your own custom events so that you can listen for them inside of your components and then i'll teach you the different ways to use react with forms how to style your components with css modules and use hooks within your components we'll also use react router to build a single page application so that by the end of this course you will have the confidence and the know-how to build your own react powered apps but first if you want to create a professional website then head over to code canyon the marketplace for high quality javascript and php components html5 and mobile templates and so much more the items at codecanyon can help you easily add the functionality and eye-popping visuals that you need to meet your business's goals at codecanyon you will find a massive library that contains thousands of javascript and php components and almost twenty thousand html and mobile templates you will definitely find what you are looking for to take your site to the next level the first thing that we are going to do in this course is spend a couple of lessons with just the react library we're not going to be doing anything with jsx or transpiling or anything like that well of course we will but for these first couple of lessons it's just going to be pure unadulterated javascript so what we write is going to run natively in the browser without any help whatsoever and later on we will talk about the things that you will need in order to use jsx and things like that but for right now all you need is a code editor and you can use any code editor if you have one that you like feel free to use it if you don't i recommend visual studio code because when it comes to working with javascript there is none better than visual studio code it is cross-platform there is a release for windows mac os and linux so download whichever one that you need for your environment and you'll be ready to go so let's get started by creating a new file i'm going to call this simply index dot html and if you're using visual studio code you can populate this file with some boilerplate markup by just typing an exclamation point hitting tab and then voila you have your markup and we want to reference the react javascript library and we can do this by just using a cdn so if you go to react.js.org go to docs and then over on the right hand side you're going to find a link for the cdn links and it doesn't matter there's two versions there's the development version and then the production version you can use whichever one that you want since this is quote unquote development we are going to use the development so just copy those links paste them into your document and then all we need to do is just write some javascript so let's have a script element and inside what we want to do is build a user interface with javascript and react now to do that we need to create some elements so the react library gives us a method called create element and we create our user interfaces by creating these elements now this isn't technically an element this is more or less a descriptor of an element and so what exactly does that mean well an element typically has some kind of type like a tag name so in this case let's create a div element that is going to be the first thing that we pass to create element elements typically have some kind of attribute so for the second argument that we pass to this create element it's going to be an object and the property names are going to be the names of the attributes that we want to provide for this element so let's set an id attribute to the value of message and then we want to specify what this element is going to contain now of course not every element is going to contain anything but in this case it kind of makes sense to contain a message because that's what we gave its id so let's just have some text we'll have our traditional hello world now because we are creating this element we want to assign this to a variable so let's just call it hello world element and then all we need to do is render this element so that we could see it inside of the browser but to do that we need a placeholder in the page so that we can tell react that we want to render this hello world element inside of a placeholder so let's create a div element an actual div element here let's give it an id of app and this is going to be our placeholder so that after we create this hello world element object we are going to use react dom this is a library that is built specifically for working with the dom essentially and we're going to call a method called create root basically creating a root that we will then render our hello world element inside of and we need to pass the actual dom element object so that is our div element that has the id of app that is the root of our application and we want to render our hello world element so there we go by using react we have created an element it will be rendered as a div element that has an id of message and it's going to contain the content of hello world so let's run that and ideally we would be running this from a web server however we don't have one running right now so we can just simply run this within the browser itself and everything should work there we have our message hello world but remember that there are some very specific things about this there should be a div element with an id of message that contains this so let's inspect this so that we can see it inside of the document so here we have that div with an idea of app that is the root that we created and then inside is the div element that we created with an id of hello message and then the content of hello world so that's great let's add some styling here and one of the best ways to do that is with a css class so let's add just a simple css class we'll call it bold text and we'll set the font weight to simply bold and to apply this class to our div element that we are creating we simply just need to add this attribute to the object that we are passing to create element so we can have class and then we will use our class name bold text now first we're going to run this and we are going to see that it works but class is a reserved word but javascript is very quirky in that it allows you to use reserved words as property names in an object i don't know why they haven't decided to go ahead and make that an error it will definitely break some people's code but personally that's fine because it is rather confusing but here you can see that our text in the browser is bold if we look at the output html we can see that the class attribute is set on that div element and it is set to bold text however we don't want to use a reserved word because there will eventually hopefully be the day that this would be an error the class word should only be used when creating a class so instead of using class we want to use classname and we are going to see that it is the same result the text in the browser is going to be bold and then of course the html output is going to have a class attribute set to bold text so even though right now we can get away with using just class don't use class name now of course remember that this is javascript it is case sensitive so there is a difference between classname with an uppercase in and classname with a lowercase in one is going to work the other is not now remember that i said that whenever we call this createelement method we aren't actually creating an element we are creating an object that describes an element that logically doesn't make a whole lot of difference at least from our perspective but behind the scenes it makes a world of difference because one of the beautiful things about react is that we no longer have to worry about manually changing and manipulating the dom react is going to do all of that for us based upon the changes that are made to the elements that we create and the data that they contain that's kind of why it's called react it is reacting to changes but from our perspective we don't really need to know that this hello world element object isn't an actual dom element object but if you want to know a little bit more as to how react works behind the scenes it's kind of important there so let's go back to the browser and let's open up the console let's refresh the page so that we can see this element object you can see that well it's just a javascript object it has a type that you can see is div but notice that there's not a property called attributes or anything like that instead it's called props and that is really what i should be calling that object that we passed to the create elements method because here you can see the id it's set to message the class name is set to bold text and the children is also being added to this props object here now props are very special and we will talk about props in the next lesson because props are how we pass data to an element and what exactly do i mean by that well let's assume that this message element that we've just created this is some functionality that we want to reuse throughout our application now of course we can go ahead and we can just copy and paste this code but we know that there are different ways of reusing code we can write functions we can write a class and create instances of that class and there's a lot of ways to reuse code so in the next lesson we are going to look at what are called components it is essentially the way that we reuse functionality in our react applications components are the building blocks of react applications and i like to think of components as functions because there are a lot of similarities between the two like for example if you're building just a regular application you're going to write some functions some of those functions you will reuse throughout your application some of them you'll only use once and that's okay the idea is that you've taken an application and broken it up into smaller functional pieces and that makes your application easier to develop and maintain that is exactly what components are for react and the reason why i say i like to compare components to functions is that we can use a function to define a component now we can also use classes but we'll talk about classes later right now let's just focus on functions so we have some functionality that we would basically want to reuse we are displaying a message but we want to be able to supply the message so that we can display anything that we want so if we were writing just a normal function it would look something like this we could call it display message where we could pass in the message and then we can just take what we have whenever we create this element and this function is going to return that element so that we can simply just call display message pass in hello world now that of course isn't going to work yet because we need to modify our function so if we're going to create multiple elements we don't need the id so let's get rid of that and then as far as the text is concerned we'll simply just use the supplied message so there we go let's go back to the browser let's refresh we see the same result to prove that it's working let's change the text hello result and there we go so we can see that this is working if we look at the output it is still giving us essentially the same thing of course the id is now gone the text is going to be different because well that's what it does but everything else was basically the same so the end result is great now we don't have a component yet we have a function that with a few modifications can be a component so the first thing is the name a component is typically named a noun so even if that component is going to do something like displaying a message we typically just call it like message and they begin with an uppercase now of course they don't have to this is all convention but if you're going to look at other people's code this is typically what you're going to find and if you want people to understand your code i highly recommend that you follow the convention as well so the first thing is the name the second thing is the data that this function is going to accept a component doesn't accept individual values like message and if we had something else that we wanted to supply no instead what we have are called props the props are essentially the object that we pass to create element so classname is a prop id was a prop in this particular case our message component is going to have a prop called message and we access that by simply going props dot message so there we go the last and probably the most important thing is that we return a react element because components return react elements they do if they don't they're not a component so we are already doing that so we are good there so then the question becomes how do we use this do we just simply call it like a function no that would be nice but no instead what we have to do is create a message element because remember i said that a component has to return a react element well this is essentially going to be an element that we will create which means we have to use the create element method we specify that we want to create a message element we are not calling this like a function we are just using the name of the function and then we supply the props so we would have our message of hello world and then that should be it so let's go back to the browser let's refresh and we see hello world now let's take a look at the markup notice that it is still mostly the same we end up with just a div element that has our message there's not a message element that is being rendered in the browser that's because our message element is really just a component that creates this div element so one way to think about a component is that it defines elements because that is essentially what we are doing we are defining a message element that we are using within our application so now the question is why why would you do this because we took something that was much easier to use that display message function and now we have to go through all this rigmarole and the reason is very simple because we don't do this we use tool chains i mean yes you can technically create an application with just pure javascript and the react library but you're going to have to write a lot of extra code so by using the tool chain our code could become something like this to where we use actual elements inside of our javascript that looks very wrong but that is what we do and that makes this whole idea of components much easier to use now of course this is not going to work in the browser because no browser natively supports what's called jsx which is what this is this is javascript and xml so what we are going to do in the next lesson is walk you through the things that you need to use react with jsx and all of the new features in javascript that's what we refer to as the tool chain when it comes to development tools especially for client-side development really the first thing that you need to download and install is nodejs now it's not that you're going to be writing for node which you can absolutely do if you want to but we install node.js because it gives us access to what's called node package manager or we just call it npm and this is a tool that we use to manage the dependencies for our applications and there are a lot of tools that are built for npm like for example we are going to use a tool called create react app and the purpose of this tool is to create a react application but this is going to give us the entire tool chain that we need so we don't need to install things individually and configure them and all of that stuff this is going to give us a react application ready to go out of the box ready for us to start developing but it's not just for developing with react npm is an integral part of modern client-side development so it makes sense to go ahead and install nodejs so go to nodejs.org download and install the lts version the version number doesn't necessarily mean anything for us unless if you're going to actually develop applications on the note platform lts stands for long term support which makes sense that you would want so go ahead download and install it's a very straightforward installation just take the defaults and you will be good to go now one other thing that i want to talk about is the react developer tools this is an extension for chrome and chrome based browsers there's also a version for firefox and this isn't necessary but it's a nice tool to have so i recommend that you install it for your browser because we will be using it some in this course and if you continue to use react within your applications it is a very useful tool alright so after you have installed nodejs you will want to go to the command line because npm is a command line tool and we are going to run npx this is going to execute the create react app tool and then we need to specify the name of our react application let's let's just call this react fundamentals press enter and then this is going to essentially create a new project for us with the latest versions of react and all of the other tools so this says that it needs to install the following package create react app okay to proceed and this might take a few minutes depending upon your connection and machine but when it's done it's going to tell you what you need to do first of all we need to cd into this new directory because it created our project in the directory that is named whatever name we gave it and let's go ahead and fire up our code editor and then back in the command line we'll say mpm start this is going to start our application so behind the scenes what the tools are going to do is take the javascript and the jsx of our project and it's going to what's called transpile it transpiling is a lot like compiling when you write applications with c or c plus plus and you compile your code you are essentially translating your c and c plus plus code into what's called byte code or machine code something that the computer will understand and execute well transpiling is very similar except that in our case it is taking our javascript and our jsx it's converting that into javascript that the browser understands so that the browser will then execute that code so there is a building process that has to take place and then as you saw it loaded it up in the browser and this is the result of that whole process so in the next lesson we are going to take a look at jsx because one of the whole reasons why you would want to use this tool chain is to use jsx within your applications we use tool chains as we develop our applications so that we can use javascript features that browsers do not support because the tool chain will then transpile all of our fancy javascript into what the browser can understand this means that we can write much more expressive code and dare i say code that's much easier to follow so let's take a look at index.js this is inside of the source folder inside of the project that we created in the previous lesson and you're going to see well this the first few lines are importing things that are going to be used inside of this file now these are modules if you're not familiar with modules that's okay we will go over modules as we need to basically these are individual files that exports objects or functions or something that we might want to use inside of another file so that is what these lines are doing they are importing those things so that we can use them here but on line seven we see that we are creating the root and then we are rendering some things inside of the root we have done that before if we look at index html from earlier in this course we create the root and then we render an element and that is exactly what is being done except that now we can use actual literal elements inside of our code as opposed to using the react library to create an element object so this is going to look very strange we have xml inside of javascript that's why it's called jsx it's javascript and xml and here the application is rendering an element called react.strict mode well as that is rendered in the browser there's really nothing that's rendered as far as the strict mode that is being used here as a development aid this can help spot problematic code especially legacy issues which we aren't really going to have to worry about but it's a good idea to leave that in there more importantly is the use of app now app is being imported online for from app now this is app.js we don't have to use the js extension as we are importing javascript files the reason is because one of the tools in this tool chain is called webpack and it will know whether or not it needs to import the javascript file called app.js so it's doing a little bit of magic behind the scenes that we don't have to worry about but let's open up app.js and despite the fact that there is some actual elements inside of this file this is going to look somewhat familiar in that we have a function that is returning a react element that is exactly what we did inside of our code we have a function called message that returns a react element so this app function is a component it's not doing anything with any props that are supplied to it because really none are passed to app but this is javascript and xml we can use literal xml elements inside of our code so this looks like html but it's not it is xml and this is an important distinction because there are very big differences between the two so the first thing that you need to be aware of is that this is xml we have to follow xml rules that means that every element has to be closed so if the element can have children like the div element it needs to have an opening tag and then a closing tag if it doesn't have any children it can be a self-closing tag but if the element doesn't have or can't have children like the image element here then it needs to be a self-closing tag so that's the first thing the second thing is that attribute values that are strings have to have double quotes so here classname is being assigned the string value of app the alt attribute on the image is being assigned the string value of logo now i know that that looks rather obvious but look at the source attribute on image that is not a string that is a javascript expression so one thing to remember is that even though this is xml this is javascript and xml so we can have javascript directly inside of our markup and whenever we want to use literal javascript inside of our markup we put that inside of a pair of curly braces so you can see that this is importing logo from logo.svg so it is using that actual reference as the source here and that's also one of the benefits of using a tool chain in that webpack is loading all of this stuff as it is building our application and it is going to optimize it so it'll optimize images css javascripts everything but i'm getting off into the weeds here so elements have to have an opening and closing tag or they have to be self closing string values for attributes have to have double quotes the next thing is that if it looks like an html element it has to be in all lowercase so this div element cannot begin with an uppercase d it has to be all lowercase and that brings us to something else remember that this is javascript javascript is case sensitive so there is a difference between div with an uppercase d and div with a lowercase d so just about everything that we do inside of our files have to take that into account but really that's easy to do because we're in javascript it should be case sensitive anyway the next thing to be aware of are javascript keywords like class if you'll remember from earlier in this course whenever we wanted to apply a css class to an element we used the class name prop we essentially do the same thing inside of our markup because class is a reserved javascript word so the class attribute becomes classname the for attribute well we have a for loop in javascript so this becomes html4 inside of our markup the next thing is that props which are essentially attributes on our elements use camel case so class names camel case if we wanted to pass some other kind of prop like if this was for displaying somebody's first name it would be first name in camel case and once again it is case sensitive and then finally what we have here is an xml fragment and fragments and then finally what we have here is an xml fragment a fragment can be only one element now it can contain children just like this div element has a header that is its child but the return statement for this app function can only return one element it cannot return two elements in fact if we try to do this not only is visual studio code going to holler at you which it's doing to me but we're going to see an error inside of the browser adjacent jsx elements must be wrapped in an enclosing tag so there you go and really one last thing and this is more convention than everything else but notice the return statement we return the element that is wrapped inside of a set of parentheses now we can get away by not using the parentheses but remember that this is javascript javascript has this feature of semicolon insertion so at the end of this return statement it's going to insert a semicolon and the app function is not going to return this div element we can put the opening tag for the element on the same line as returned but then you know our white space gets a little wonky so what we end up doing is just wrapping our element with a set of parentheses that way our markup is nice and aligned and it's a lot easier to read so there we go those are the basic rules of jsx and it's not really something that you can opt into well of course jsx is something you can opt into but the rules themselves are not we are bound to the rules of not just javascript but xml and one of the great things about that is if we mess up we're going to find out eventually either in the code editor or in the browser whenever i create a new project i typically delete just about everything that comes in that new project for a variety of reasons first of all i like starting with a clean slate but i also like practicing because programming is just like any other skill and the more you practice the better at it you become so that's what we are going to start with in this lesson let's just delete everything inside of the source folder and this will give us the opportunity to talk about some very important things about react because some of the things are hidden behind the scenes like for example our application just seemed to work as is and now it's definitely not because we don't have any code there but the entry point for a react application is inside of the source folder and it is the index.js file so let's go ahead and let's create that file because without it our application is not going to work and the first thing that we should do is import react and the reason why we want to do this is because well this is the library this gives us the things that we need to build our application sometimes we won't always import react we might import some separate pieces of react but we'll come to that at another time so we want to import react and in this particular case we also want the react dom because if you'll remember we have to create the root of our application so that we can render our application inside of that root so that is from react dom client and we want to create that root so let's go ahead and do that we'll just call this variable root and we will use the create root method and we want to pass in the element that is going to serve as our root and then we need to talk about where this element is so let's go to the public folder and let's open up index.html this is the template of our website so whenever react or rather whenever the tool chain builds our application and then we view it inside of the browser it is going to use this file this index.html inside of the public folder as the template and then it's going to inject all of the javascript that we write inside of this page so right here inside of the body there's this div with an idea of root this is the root of our application now we can come in here and we can make some changes in fact if we wanted to we could pull in some global assets like if we wanted to use bootstrap for our css framework or if there were other resources that we might need we could put that inside of this file here or at least we could reference those things but there's a lot of things that we also want to use npm and webpack in the tool chain to manage for us as well so when it comes to something like bootstrap we can do that through npm which is probably something that we will do so this is where the route is so we want to specify that element so we will use the id of root and then we want to render something now we don't have anything to render so let's write something let's write a component and this could be considered the main component of our application and what you would typically find in other people's projects is this main component is called simply app and if you'll remember from just a few moments ago before we deleted everything inside of the source folder that is what was here originally there was this app component now you already know how to write a react component it's going to be a function we can have props but i don't think we need props at least right now we can always add them later if we need to and we want to return a react element and we're going to use jsx and you learned from the previous lesson that we typically wrap our jsx in a set of parentheses this makes it a lot easier to maintain and read in this particular case though our markup is going to be very simple we'll just have a div element that the text will be hello world and of course it's very simple but it at least gets us started so we learned in the previous lesson that jsx is xml we have to follow the rules of xml which means that we can return a single element which we are doing our element has an opening tag and a closing tag and we've wrapped everything in a set of parentheses to make it a little bit easier so everything's great and good except that this is a javascript module now if you're not familiar with javascript modules it's very simple it is simply another file and everything inside of that file is private by default so we want to use this app component inside of our index.js however we can't because as it is right now this app function is completely private it is not accessible from outside of this file so what we want to do is export that so that it can be used and we can export things in a couple of different ways the first way is to export default this means that we are going to export one thing only which in the case of our app component that's all that we need export default now you could see this written in a variety of different ways in some projects you'll see it written like this where the function is defined first and then it is exported you might see it to where the function is in line with the export statement and really it just depends upon the project that you're working in or the developers that you're working with i am going to use this approach to where we define whatever it is that we want to export and then we will export that now there's another way that we can export things from a module and that's just by using the export statement but that is for exporting multiple things and in this particular case we don't need to export multiple things so we'll just use export default so with that done we can go to the index file and we want to import app from app now we can use the js extension or we can omit that and then we want to use this component and we can do so very easily by just using app as an element remember from a couple of lessons ago that a component defines an element that is exactly what we have here we have a component called app that defines an app element so we use it as an element but remember though that there was also the react dot strict mode element and we could use that and whenever we go to the browser we're going to see the result of our code and the reason why we didn't have to refresh or you might have to refresh sometimes it varies but the tool chain behind the scenes is watching the files as changes are made it's going to rebuild our application and it should also refresh the page in the browser it doesn't always work sometimes we do have to manually refresh but in this particular case it refreshed for us so now we have our own starting point in the next lesson we are going to build out this app component react was created for building user interfaces and this changes the way that we develop web applications like for example let's assume that we were building a static website so let's look at index.html if we had a static website of course all of the different pages within the website would need to have the same look and feel otherwise the same ui so we would define that user interface through the markup inside of each one of those html files which would be a nightmare that is what you typically have to do with a static website if we were using some kind of server-side technology like if we had php and laravel or if we were using c-sharp and asp.net they have tools to make it easier to build a cohesive web application but still ultimately we would be defining the user interface for our application through html so it would be directly inside of the html with react we define our ui as components so essentially what we see in the browser is the result of building and using a lot of different components so if we wanted to add a nav bar to our web application we would write a navbar component and we would be able to use that component throughout our entire application and that's what we're going to do in this lesson but first of all i want the navbar to look halfway decent so i'm going to pull in bootstrap because it has some built-in components that make it easy to use these aren't react components these are just bootstrap components like the nav bar or alert boxes or things like that so the first thing we want to do is install bootstrap to our project and we want to save this as a dependency and the reason why we want to save it as the dependency is so that our project would then know that bootstrap is a dependency and if we ever needed to reinstall the project then all we would have to do is say npm and install and it would install all of the dependencies if we didn't save bootstrap as a dependency then our project wouldn't know that bootstrap was being used and so if we needed to reinstall it again then bootstrap would not be installed but with it being saved then we're good to go let's go ahead and start our application once again this is going to of course build our application it's going to fire up another tab for our browser but when that pops up we'll just ignore it for now so now that we have bootstrap as part of our project we want to use it within our application and if this was a conventional application either a static website or if we were using some kind of server side technology we would typically add a link element to our markup where the href was either going to be the bootstrap css file on our server or if we were going to reference a cdn or something like that we essentially kind of do the same thing except that we do it through javascript and this is going to look very weird because we are going to be importing css through javascript but this is essentially what we do and i'm going to do this inside of index.js because this is going to import the css into the entire application so that we would be able to use bootstrap's css classes anywhere so to do that we will simply just import bootstrap that has a dist folder for distribution we want css and then there's bootstrap.min.css and that is going to pull in the css into our application so that if we take a look at the browser now we well let's go to the right tab well this should have updated let's refresh and we can see that the style of that text just changed and let's take a look at the source that is actually being sent to the browser there's not a mention of any css and that's one of the cool things about using the tool chain is that since we have bootstrap as part of our project it's being run through webpack and it's being bundled into the rest of our application's code so this bundle.js right here this is the only javascript file inside of this webpage and if we take a look at this then we're going to see some things that will look familiar because this is the result of the tool chain taking all of our code and now it's also pulling in the css from bootstrap and it's injecting it into the html so here we can see that this is app.js doesn't really look a whole lot like the code that we've written but this is part of the idea of transpiling it's taking the code that we've written and transpiling it into something that the browser can recognize and here we can see our app component it looks different than the code that we wrote but once again that's the nature of transpiling all right so now we have a reference to bootstrap let's go to our app component and let's just make sure that everything's okay we're going to add a class or css class to this div element and let's just use bg dark that should change the background color to dark and it does so we're good here we are going to build another component we're going to call this navbar so let's create a new file and we will have our function we'll call it nav bar and let's go ahead and let's say that we're going to have props because this is going to have a navbar that will have the title of react fundamentals but then we might also want to provide a subtitle for the individual page so we are going to return some markup here we'll have the nav element and there will be some boilerplate css classes necessary for using the navbar component then we need a div element that will have a css class of container fluid and then we will have the navbar branding which according to the bootstrap documentation we can have just a simple link the css class is navbar brand and we will have an href that won't take us anywhere then we will have our text of react fundamentals and then this is where we can display our props now remember that whenever we want to use actual javascript inside of our jsx we surround it with a pair of curly braces and we will say props dots and we'll just say that we will have a title prop so that's going to be our navbar we of course need to export default navbar and we're going to use this inside of our app component because this should be present just about everywhere so we want to import nav bar from the nav bar module and then we want to use that but remember jsx we have to return a single element from our components so to start we're going to have a div element that's going to wrap around our nav bar as well as the content and then we will see what that looks like in the browser so with that change we should be able to there we go we see react fundamentals uh let's provide a title for our nav bar let's say lots of components because that's essentially what we're going to have and there we go we can see that we are providing data to that component let's say though however that i don't really want to use a div element to surround the nav bar and then whatever content that we are going to display in the page because that could be disruptive as far as what's actually rendered so if we inspect this we will of course see a div element that wraps around the nav bar and the content so here's that div here's the nav bar here's the content so what we could use is called a fragment this comes from react so we would need to import react and instead of using the div element here we would use react dot fragment what this does is give us a single element that we can return but nothing is going to be rendered in the browser as far as that element is concerned so if we return back to the browser we can see that we have root and then directly inside of root we have nav and then we have the content that's all well and good we could simplify this a little bit by just importing fragment because fragment is exported individually as well and the way that we do this is by using a pair of curly braces and then specifying the things that we want to import so if you remember whenever we export defaults we can only export one thing like the nav bar well the react module actually exports multiple things so one of those things is simply fragment so if we import just fragment we're going to end up with the same result but it makes our code a little bit easier to type out or we could do this we could not import anything at all and this is going to look a little weird but this is probably the cleanest solution we can have an empty element so that the opening tag is empty there's nothing there and then the closing tag is nothing there but this essentially translates into a fragment so if we go back and look once again we have the root we don't have a div that's going to contain the nav and then the content we have the nav as a direct child as well as our content there so i guess let's change the title here this isn't lots of components let's say that this is using fragments but one thing i'm noticing is that the content is being hidden uh we have the navbar which is of course taking up the amount of space that it needs to but as i hover over the content we see that that is still being placed at the very top of the viewport we want to push that down so that it is below our nav bar and we can do that with css so in the next lesson we are going to add custom css to our index in the previous lesson we started to build a ui by adding a nav bar to our project and this is a component we called it navbar it has a title prop so that we can change the text whenever we need to in fact let's go ahead and let's do that so we are using that navbar component inside of app and we talked about fragments in the previous lesson in this lesson we are going to very briefly talk about css and separating javascript and jsx which sounds kind of weird because we are now in this environment where well it's jsx our javascript is intermingled with our markup but there is some places where we can separate the two and you will learn about that in this lesson so let's first of all talk about css because we have some content that is currently being hidden by the nav bar and one of the easiest ways that we could fix this is just by adding some padding to the top of the body so we want to add some css and we can do so in a couple of different ways first of all is to use the style prop if you are using a what would normally be an html element there is a style prop however it's not like the style attribute instead it wants a javascript object where the properties are of course the css property names and then their values and we will talk about that at a later time for right now though we are just going to write some css inside of another file and import that because that's one of the easiest ways to add style but it also behaves a little bit differently than what you might expect because whenever you import css it is done so globally so if we were to import a css file inside of our navbar component it is not scoped to the navbar component it would be globally accessible so whatever css classes or rules are defined inside of that css file we could use them throughout the project so we are going to create a new file and generally what you will see is the css file name is going to be the same name of the javascript file so for me it makes sense that what we are going to add would be considered global even though it is technically global we would consider the rules that we are going to write as global so for me it makes sense to import this inside of index there is no magic in the naming of these files that's just kind of the convention because it makes things a little bit easier to identify and find and maintain so as far as the css that we're going to add we're just going to add some padding to the top of the body and we're going to change the background color of bg dark so with that saved all we need to do is import that inside of index and then we will be good to go so let's hop on over to the browser this should automatically refresh and oh yeah the content is using that bg dark background isn't it so let's go to app and let's change that so that instead of bg dark let's go ahead and use container let's also change the class from container fluid to container inside of nav bar just so that there's some breathing room between the left side of the screen and then the text that we have so now we can see our content and that's great but we're going to replace this we are going to write a component that will display a list of things we will supply that list as an array so it's going to look like this we'll just simply call the component list and then we will supply two things we will supply a title because we kind of want a heading for the list and this is going to be just simply a list of guitars and then we want to provide the items that we want to list now this is going to be a javascript array and we can define that right here if we wanted to so we could have a strat and then a les paul and then let's also have an explorer so we can define that right here or what we could do is define a variable inside of our component here we could just call it guitars and that would be our array and then we would use this variable as the value that we pass for the items prop now remember that since we want to use actual javascript inside of our jsx we have to wrap that javascript with a pair of curly braces just like we did in the previous lesson for the title prop in the nav bar so it's the same idea we are passing an actual javascript array to the items prop so we need to use the syntax to make that happen so this is essentially what we want we just need to implement that so that it works let's go ahead and let's import this even though it doesn't exist that's okay because we are going to create that right now we'll call it simply just list js and we will have our function that has our props let's go ahead and let's define the return statement that's going to have our fragment as the return element because we're going to have two things we'll have the heading or the title so let's go ahead and let's output the title prop and then we will have an unordered list and let's go ahead and add in just a list item so that we can see something in the browser just to make sure that everything worked and of course we want to export the list there so with that done we should be able to see our list and we do so now we want to take that items prop and we want to essentially generate the list items and this is where the idea of separating your javascript and your jsx comes into play because while we could technically generate that right here inside of our jsx we don't want to do that because in order to generate multiples of these li elements we essentially need to write some javascript code we need to loop over the items array so we want to separate our javascript from the jsx so before the return statement this is where we are going to have the code that's going to build our list of li elements because when it comes to our jsx we want that to be as declarative as possible that's what makes it easy to read and understand and maintain so how we do this is actually very simple we're going to create a variable called items and we are going to use the items prop and remember that this is an array so we have all of the array methods at our disposal we can use the map method to transform this array of strings into an array of react elements so for our callback function we'll just take that item and return a list item element where we will display that item so it is somewhat mixing the javascript and jsx but it's more along the lines of separating logic from the display or the view or whatever you want to call that so what we end up with is an array of li elements here that we can then use inside of our jsx so whenever we go back to the browser we should see our list of guitars strat les paul and explore so ultimately it's a very simple concept but it is something that you will do especially as you write to more complex components in my mind i think of okay i'm going to set up everything i need so that i can easily display that information that's just how i mentally approach this we write software to work with data and whenever we use react to build our user interfaces there becomes this very tight relationship between our applications data and the components that we use to display and work with that data so in the next few lessons we are going to be focusing on data and how we work with data and how changing data can affect our components and in this in the next lesson we are going to specifically focus on props because props are the primary way that we provide data to our components so in this lesson we're going to go over some of the basics of props like for example in order to pass data to a component you use props and the way that we define props is by using attributes the prop name is the attribute name and then of course the value is whatever value we assign that prop and we can have as many props as we want there really is no limit and there's not a lot of hard and fast rules as far as how we name our props but of course we can't use a javascript reserved word and it's a good idea to use camelcase and just by specifying a prop that is going to be data that is going to be passed to that component now the component doesn't have to use that prop like for example we now have specified a text prop on our list component but of course the list component doesn't do anything with that text prop so as far as what we see in the browser there's no change because we're not doing anything with that prop and as i've said before passing props is a lot like passing parameters to a function in fact let's do this we can use our list component as a function because it is after all a function and we could pass in it has to be in the form of an object because well our function is expecting an object but we can pass an object that contains our props so we can have our title which is going to be guitars and then we of course need the items prop which is going to be the guitars array and then this is going to give us a result which i've just called stuff and we can use this inside of our jsx so that instead of actually using the component directly inside of the jsx we are just referring to the result of calling that function and we get the same results i'm going to refresh and voila it's the same thing so it is easy to equate a component with a function and whenever you start thinking in that mindset then it becomes very simple as far as props are concerned because we can pass any kind of value as an argument to a function therefore we can pass any kind of value as a prop so for example whenever we pass data to our list component our title prop is a string our items prop is an array and if we wanted to pass a function we could do that for example if we wanted to define what would essentially be an event on something we could pass in a javascript function that would do something whenever that occurred in fact that's one of the ways that we can work with data which we'll talk about at a later time so we can essentially pass whatever we want to as a prop to our components and we can pass as many props as we want to a component now the last thing and this is probably the most important is that whenever you pass data as props to a component inside that component the props are read only so for example inside of our app component we define an array called guitars we then pass that array to the items prop for our list component so inside of list the items prop is read only we cannot change it in fact if we try to change it we are going to get an error let's just assign a new array to items and right off the bat we can see that the browser doesn't like that and we can look at the console and we will see the error cannot assign to read-only property items of object now the reason for this is because eventually we are going to get to the point where we're going to use what's called state state is data that is essentially maintained inside of a component and react will automatically manipulate the dom it will re-render what is in the browser when that state changes and props are essentially the mechanism that's used for updating components so essentially that means that while we can't change the items prop inside of list we can definitely change the array that is passed as the items prop to list so eventually we are going to get to the point to where we can manipulate this guitar's array and whenever we do that react is going to recognize that change and it's going to re-render the list component in the browser so that what we see in the browser is going to sync up with whatever data was changed inside of the app component and this essentially means that data flows down in react if you know anything about angular you know that you can have a bi-directional binding meaning that data can flow up or down well react is not bi-directional it is unidirectional and it goes from top to bottom from parent to child now there are some things that we can use for a child to notify a parent that it needs to update something like an event but once again we will talk about that at another time so in the case of our project as it is right now the app component has an array called guitars and we are passing that data on down to the list component so that it can display that in fact let's create another component we'll call this list item because well why not and this is going to essentially render an li element so we're not really getting a whole lot of functionality as far as this is concerned but this will give us the opportunity to see that data just keeps flowing on down from parent to child and then from that child's child and then if we even need to go further down from that child's down to its children so in this particular case we will return an li element where we will display the text for this item so we want to use this inside of list and we also need to export that item as well so let's do that we'll just export defaults list item so that inside of list we can build this list item that will have the text prop equal to the item that we have so now we have data originating inside of the app component flowing down to the list component that flows down even farther into the list item and of course if we view this in the browser everything looks as it should in the next lesson we are going to continue looking at props and you will learn how to validate incoming props within a component when you pass data to a component the component really doesn't care about the type of data that you've passed as the prop and one of the ways that you can think about this is like a function have i mentioned that components are a lot like functions i think i have well when you call a function you can pass anything to that function now the function might not know how to work with whatever you pass to it but you can pass anything to the function the same is true for the component so our list component has an items prop and right now we are passing an array but what happens if we pass a string well let's give it a shot really doesn't matter what that string is the application is not going to work and the reason is very simple because even though we passed data to the items prop inside of the component it's expecting an array and if we take a look at the console then we are going to see the actual error it says props.items.map is not a function and that's kind of explicit as to what the problem is we can look at that error and we can definitely see oh okay well we passed an invalid value for the items prop but sometimes the error is going to be vague and then we have to stop whatever we're doing and we have to debug our application and try to find the problem so one of the things that we can do to help ourselves find issues is to validate our props let me preface this by saying that this is not going to save your application from failing it is however a useful tool for development so that as you run into issues related to props they can help you spot those problems easier so that you can fix them and then get back to developing your application so validating props is entirely optional you don't have to do it because when it comes to actually running your application you're at the mercy of the data that your application is actually working with if there's an issue with the data itself well your application isn't going to work so we are going to add some validation to our list component because we want to ensure that the items prop is an array and the first thing that we are going to do is import prop types from prop types now this is a package that was installed whenever we created our project with create react app if you have a project that was not created with create react app this is not going to be available to you you have to install that using npm which is quite simply the command npm install prop dash types and you would want to save that and prop types are going to give us the ability to validate our props so we do that by adding a static property to our function or to our component called simply prop types now notice the casing here prop types that we import has a capital p the property on our component is a lowercase p but this is going to be an object where the properties are the props that we want to validate so in this case it would be items and then we use prop types that we imported and this has some predefined values that we can use to validate so our items needs to be an array we will use proptypes.array we could do the same thing for the title prop as well so let's go ahead and let's say that title needs to be a string and that's it so let's save that let's go to the browser and we are going to see the same error although let's do this let's clear out the console let's refresh the page so that we can get just the errors that we need there is the error that we saw before that props dot items dot map is not a function but let's scroll on up and we can see the first error failed prop type invalid prop items of type string supplied to list expected array so okay let's fix that let's go back to app let's change that to our guitars array and of course that is going to go away or at least the application works if we were to reload this that particular error would go away but let's pass something other than a string to the title prop let's pass in the numeric value of 10. now the application is still going to work because the value of 10 can be coerced into a string so that's fine but we still get an error in the console failed prop type invalid prop title of type number supplied to list expected string so as i mentioned it's not going to save your application from either not working or behaving incorrectly or i i guess i should say behaving unexpectedly but it is going to give you an idea of what the problem is if it is related to props now these two props are kind of important the list needs to have a title it also needs to have some items to list otherwise what's the purpose of using the list so really we could also say that these are required by using the is required property so props array is required props string is required so now if we omit one of those let's omit the items and once again it's not going to prevent our application from failing but whenever we look at the errors we can see that there's a failed prop type the prop items is marked as required in list but its value is undefined so once again the error itself is very clear and tells you what the problem is so that as you're developing your applications it gives you a clear path as to what you need to do to fix it well let's add another prop to our list one that's going to serve as the background color for our title and let's say that we only want one of two values so we'll call this prop simply background and the value that we will pass in is one of the colors from bootstrap so let's say that it can be either primary or secondary well that of course means that we need to validate that but prop types gives us the ability to do that so we want to validate the background prop we will use prop types and it has a method called one of you'll pass in an array that contains the values that this prop can be so that's going to be primary and secondary so that if we pass anything else once again it's not going to prevent our application from working but we will get an error if we pass something other than one of these two values so if we pass in danger then of course whenever we look at this in the browser we can see that invalid prop background of value danger supplied to list blah blah blah blah i kind of sound like a broken record i keep repeating myself but it is a useful tool now what if you have a prop that is a custom object it's not going to fit into the nice little neat box of an array or a string or number or boolean or anything like that well prop types can work for us as well let's just call this special prop and we are going to use prop types and it has a method called shape the idea being that you get to define the shape of the object so that if you pass something to special prop that doesn't match this particular shape then it would be considered invalid so if this had a name property then we would use prop types to say that this was going to be a string if we had an age then that is a numeric value so once again we would specify that it is a number and so on and so forth so that whenever we pass a value for this special prop if it has a name property that's a string and an age property that's a number then it of course passes validation if it doesn't then it fails so this can be a very very useful development tool as i've said many times it's not going to save your application from failing but it can save you a lot of time finding bugs related to props in the previous lesson you learned how to validate your props using prop types and one of the options was to mark a prop as required now as you know this is purely a development tool this is not going to prevent your application from failing if for whatever reason we omit the items prop in the browser it just fails and in production you want to avoid this scenario as much as possible because nothing is more frustrating than an application that doesn't work so instead a better option is to at least let your application work the behavior might not necessarily be what you would expect or want but a working application goes a long way towards lessening frustration on the user's part so what we want to do then is provide a default value for our important props like items in this case and maybe for all of our props it really depends upon the component and whether or not it needs those props so we can provide a default value in a couple of different ways the first would be to create a new variable inside of our list component let's just call this temp items and we're going to use the good old shorthand syntax of a default value so that if items has a value then it is going to be assigned to temp items but if it is a falsie value then we are going to assign it an empty array and then instead of mapping over prop dot items we will map over temp items that way our application will work um no it won't we need props.items this way our application will work the behavior isn't necessarily going to be what we want because we want to see the list of guitars but at least the application is working so that's one way the other way is to use something that's built into every component and that is called default props so we use it kind of like the prop types in that it needs to be a static property on our component itself and it's just an object where the property names are the props and then their values are the default values so here we can assign an empty array to items if items is omitted and let's clear out the errors let's refresh the page and we can see that it still works now notice however that we do not get the error that we would expect to get because items is required that's because we have a default value so it's kind of a toss-up do you want a default value or do you want an error message telling that your application completely failed because it didn't have an items prop i would prefer to have a default problem so let's do the same thing for background let's say that if we don't have a background then let's set the default value to primary and honestly i don't know what the result is going to be here so let's refresh i would expect we would still get an error because the default value isn't going to change the fact that we supplied a background value of danger so that makes sense but if we omit the background prop then we would see that error go away and even though we aren't really doing anything there let's change that so let's create a variable we'll just call it css and we want to use the css class of bg dash and then whatever is our background prop so that then for the class name for our h3 element we could set that to our css variable so now the defaults primary we see primary if we provide a different value for background like for example if we give it an incorrect value of danger that's going to apply the danger color to our h3 element but at least the application's working and we get the error that we would expect saying that danger is not in the accepted list but if we change that to secondary then of course we see the secondary so while prop validation might not necessarily be something that you want to do all of the time or any of the time defining default props is something that you would probably want to do if anything it could prevent your application from catastrophically failing and there's something to say about that if all you want to do is display static content that never changes then all you need is props and there are some valid reasons why you would want to use react for static content however the whole reason why react exists is so that we can build interactive web applications so that when data changes the ui will automatically re-render and update to be in sync with the data and the mechanism that react uses to update our ui or re-render our components is called state state is really nothing more than information that is managed by a component and that data can change throughout the lifetime of that component so let's call this lesson getting started with state and we aren't going to use our list in this lesson we will revisit it later on to add some interactivity to it for now we are just going to create a new component called counter it's going to be very simple it's just going to count but we can add some flexibility here so that we can have a starting point to count from we could also specify what we want to count by so that if we want to count by twos then we can supply that functionality so let's start with just outputting the information that we get with our props so first of all is going to be the start at prop which makes sense let's add some text so that we know what this is and let's do the same thing for the count by prop because that makes sense as a name for that prop and it would also be nice to have default values for these props but let's first of all have a placeholder let's use an h4 and this is where the actual counter is going to go we will of course change that later so as far as our default props let's have the start at b0 let's have the count by b1 that kind of makes sense so that if we just drop in the counter component then it will start counting like we would expect it to and of course we need to export this otherwise this whole exercise is going to be moot so let's import this inside of our app and then we'll just drop it in inside of this div with a class name of container so that if we hop on over to the browser we see the ui that we would expect we have our start at we have the count by and then the counter so let's first of all think about how we would typically implement this and i would do something like this i'd have a variable simply called counter we would initialize it with whatever was provided as the start at prop and then i would use set interval and this would call a function that would automatically update our counter with what was provided with the count by prop and i would run that function every second so that makes sense to me so that we could display simply the counter there perfectly logical it's not gonna work now we do see the number zero where our counter is but notice it's not counting and the reason is very simple we have to use state we have to tell react that first of all we want to use state but also that our state is changing so that it will know that it needs to re-render our component so the first thing we need to do is import a function called use state this is from the react library and this is what's called a hook because we are hooking into react's functionality when function components were first introduced to react they were stateless you could supply props to them and they could display the information from those props but that's it they were very very simple components but as react evolved these hooks were provided to hook into react's functionality functionality that was normally found in components that were written as a class so now we are getting to the point that we can write our components as functions and have the same functionality that we normally would if we wrote our component as a class and function components are becoming the preferred way of writing components which is one of the reasons why we focus primarily on function components and we will talk about class components later so we have this function called use state and this is actually going to return an array that contains two things the first is going to be whatever variable that we want to keep track of so that's going to be our counter the second thing is going to be a function that will set a new value for that counter so whenever we want to update our counter we call this set counter function that's going to set a new value for counter that's also going to tell react that hey you need to re-render this component so we're going to call use state we could pass in the initial value that we want to use for this counter which is from our start at prop well let's briefly talk about why i'm using a constant here as opposed to just a regular variable because it might seem wrong to use a constant for a stateful variable because the whole idea of having a stateful variable is so that it can be changed and by making it constant we are preventing any change from occurring but this decision comes from the fact that we are using a function for our component because when react re-renders our component it is going to call this counter function again for every single time it re-renders the component all of the code inside of the counter function is going to execute so that means this counter variable is only going to exist for the life cycle of this function and changing its value isn't going to trigger react to re-render the component so therefore it kind of makes sense to make it constant and in fact calling set counter really isn't going to change the value of this variable because calling set counter is going to tell react that it is time to re-render the component so that is going to call the counter function again which means that use state is going to call again and it's going to provide the new value for the counter variable so by using a constant here i'm just protecting the value of counter as it is in this particular execution of the function we're trying to avoid bugs and using a constant here gives us that ability so with that explanation i want us to rethink line six that we are calling set interval because any time that this counter component is re-rendered this function is going to execute which means that it is going to call set interval again set interval is essentially an endless loop i mean we can close it by clearing the interval but by calling set interval we are saying that we want to execute this code every second until we explicitly stop it so we don't want that because we're going to end up with two competing loops and in fact if we leave the code like this it's going to start to look glitchy and i guess that we can go ahead and we can show that so as far as our code is concerned we can't modify our counter variable because it is a constant and even if we did react wouldn't know that it had changed in that it needs to update the component so we're going to call setcounter and then we are going to provide the new value that we want our counter to have which is going to be the current value plus whatever is the count by prop and so by saving this we can go to the browser and we can see that it is starting to count but notice it's starting to kind of glitch here and there and that is simply because we essentially have two loops going and the more that this runs the glitchier it's going to get as you can see here so we don't want to use clear interval here because that is essentially setting up yet another loop every time our component re-renders so instead it makes more sense to use a set timeout so let's make that change we'll go back to the browser we need to do a hard refresh because we don't want any of the existing code to run and so now we can see that it is running just fine there's no glitching there's really nothing that we need to worry about there and so now that you know how we can use state to manage internal data and tell react to re-render our component we need to add some interactivity and the primary way that we do that is with events applications that have a graphical interface are primarily user driven we tend to react to whatever the user is doing so if they click on something or if they type on the keyboard we typically do something then now of course there are some times when we want to do something without user interaction but for the most part we typically react to whatever it is that the user is doing and we do so by using events so in this lesson we are going to talk about events primarily for these built-in components what looks like the html elements later on we will talk about custom evens because we can provide custom events for our own components so instead of having this automatically updating counter i want to provide the functionality so that we will have two buttons whenever we click on a button it will increment the counter and then whenever we click on another button it will well it will do the opposite decrement or whatever the opposite for increment is so let's add those buttons and this first button will be for counting up let's just use that terminology because that's a little bit easier to understand and so our class is going to be the primary class and then we will have simply the text of count up let's copy and paste for the countdown we'll use the danger class for this and then we just need to set up our event handlers now if you're familiar with dom level zero events those are the event handlers that we defined in our html so that if we wanted to handle the click event it would look something like this to where we would have on click and then we would have a string that would contain some javascript expression it could be a function to execute or it could just be something else well the idea in react is very similar except that this isn't html this is a react element and more specifically it's a react component and components have props props are camel cased so in the case of the on click event it is camelcased it has to be camel case remember we are in javascript this is jsx it is case sensitive therefore it's important to remember that props are camel case and then instead of supplying a string we supply the javascript that we want to execute so we need to use a pair of curly braces and we could start off with something like this it would be just a simple expression to where we essentially set the value for our counter plus what was provided for the count by and we can essentially do the same thing for counting down except that we would want to subtract the count by value and so this should work let's comment out our set timeout because we don't want this to automatically go off let's refresh and then let's click on our count up we are counting up if we click on countdown we are counting down so that's great and all however i'm not really wild about this particular syntax because when it comes to the markup i want it to be as clear as possible and if i have to decipher this mentally then that's just extra time that i have to spend doing it because i'm lazy so let's define two functions one's going to be count up which is going to essentially have this code to where we count up so let's just cut that out and paste it and then we will have the countdown function which will have a similar functionality so let's once again cut and paste and then all we have to do whenever we set up the event handlers is just reference these functions now we don't want to execute them so we're not going to have the set of parentheses after the function name we just want to say that we are going to use this count up function to handle the click event for the count up button and then we want the countdown function for the countdown button so we can go to the browser let's refresh and we will see the same functionality now one thing to remember is that since this is basically a dom event we get an event object so if we need any kind of information from the event that occurred we get one it is automatically passed to the function that is handling the event so let's write this out to the console so that you can see it and it's going to have all of the information that would normally be there for a mouse event so let's click on the count up we have this synthetic base event so we have the client x and y we have the page x and page y we have the screen x and screen y we have the target that's usually what we are after but when it comes to a mouse event any one of these would be useful to us now there are a lot of built-in events for these built-in components of course there's on click there's on mouse over there's on mouse out there's keyboard events drag and drop events i mean there's a lot that we could go over but we just don't have time to do but they are typically named the same as their native dom events you will just want to use the camel cased name instead of all lowercase and of course you will find a link in the description for this lesson that will take you to the documentation for the built-in events now that we are working with state and we are manipulating it especially through events i think now is a good time to start talking about classes even though that functions are becoming the preferred way of writing components there are still some times that you want to reach for a class and unfortunately there really is no hard and fast rule as to when to choose a class and when to choose a function i am still of a mindset of using functions for more simple components and that's just because functions were introduced as components for that explicit purpose they were very very simple they did not have state so for simple components i tend to reach for a function for more complex components i tend to reach for a class that's not necessarily right or wrong that's just how i think of things however i do tend to think that the more complex your component is the more suited for a class that it is so what we are going to do in this lesson is rewrite our counter component as a class so let's create a new file let's call it counter class and i'm going to have these side by side so that we can see both of them at the same time and the first thing that we should do inside of this file is import react because whenever we create a class we are going to inherit from the component class which is from react so let's just call this counter even though the file name is counter class we're still going to call this counter and we want to extend react dot component now we can sometimes get away with this instead of importing react we can just import component so that we don't have to reference react at all now if you need to use react in other parts of the file then yeah you would want to import react but for this case we just need component and we are going to be fine and really the first thing that you should do when you define your class is define the constructor because the props for this component are going to be passed to the constructor and you have to pass those props to the super class which is the components class so our counter class has a constructor that's going to receive the props we're going to pass the props on to the component classes constructor so that it can initialize everything that we need to and then inside of the constructor we can also initialize some other things like for example our state so inside of a class first of all we're going to use this a lot because well we are inside of a class and we have a property called state this is an object where we store all of our state it doesn't have to be simple values like our counter it can be an object that has whatever shape that we need it to it can be an array it can be an array of arrays really doesn't matter we can store anything in our state but for this component we just need a counter and we can go ahead and initialize that with the start at prop and speaking of let's go ahead and let's define the default props so for the function component default props was a static property on the function object itself it's kind of similar for a class we have a static property called default props and it has essentially the same thing so we can just copy and paste that code and we are going to be fine the same is true for the prop types so if we wanted to use prop types for prop validation once again we would have static prop types and then we would define the props and the types for those problems all right so now we have these helper functions that handle our events so these would essentially translate into methods in our class so we can almost just lift these out of the function and paste them inside of the class we do need to make a few syntax changes and we also need to address the code inside because we no longer have this set counter function instead what we have inside of our class is a method called set state and then we pass in an object that has the properties and the new values for those properties so in this case we would want to set our counter to the current value plus the count by props but remember that we are inside of the class so in order to access this information as far as our counter as well as our props we have to start with this to get to our counter we use our state and then counter and in this case we're going to increment by the count by props so we say this dot props and then count by and that will give us the same functionality so we can copy this line of code and use it for the countdown because all we need to do is change our addition to subtraction and there we go so we have our methods for handling the events now we just need to write the code that's going to render our component so every component has a render method this is the method that react executes in order to render and re-render our component now when it comes to function components the function itself is essentially the render method as we talked about a couple of lessons ago whenever react needs to re-render a function component it executes that function well the same is true for a class component except that it holds on to the class object and it just calls the render method in order to re-render that component so in a lot of ways the render method on the class is going to be a little cleaner and leaner than a function component because we don't have to have all of this extra stuff because all this extra stuff is just part of the class so what we can do is essentially take our return statement and let's just drop that into the render method we do need of course to change our references here so that in order to get to our props we have to use this in order to reference our counter we have to use this dot state dot counter and then in order to reference our count up and count down methods this dot in front of them so now let's just export this class and let's go to app.js and let's change the file name from counter to counter class let's go to the browser let's refresh so that it is completely loaded let's pull up the developer tools so that if we have any errors that we can immediately see them and let's click on one of the buttons and lo and behold we have an error cannot read properties of undefined and it tells us what it's trying to read reading set state now of course the only times that we have used set state in our counter class is in the count up and countdown methods so when these are executing this is undefined because that's exactly what it says cannot read properties of undefined so for the most part everything about this component is working whenever we set up the click event handlers we are specifying the methods but they aren't executing within the context of our component instead they are executing within the context of undefined now this really isn't a react issue although there are some other frameworks that have gotten around this particular issue but this is a javascript issue this really isn't anything new and we know how to fix this particular problem and we can do so in one of two ways the first would be to wrap the calling of these methods inside of another function and if we use an arrow function then that means that this is going to reference the component object as opposed to undefined so if we go back to the browser let's just go ahead and refresh and whenever we click on the buttons we can see that that works so that is one option however this option can get a little verbose especially if you have a lot of events and i know me personally i want to have the least amount of code inside of my markup so the other option is to essentially bind these methods to our component object and we can do that inside of the constructor so this is going to look a little wonky in that we are going to say that our count up method is equal to our count up method being bound to this and we would do the same thing for the countdown method it looks weird but it makes sense because we are essentially assigning our methods count up and count down a function object that is bound to this component instance so if we go back to the browser now we can well let's just do a refresh just to prove everything's working whenever we click on the buttons we get the functionality that we would expect now the great thing about this is that we have two ways that we can write a component and with every new version of react our function components become more and more capable like the class components there still are a lot of developers that reach for a class when it comes to creating a component because that has been normal for them for many years and in a lot of ways a class gives you more flexibility however that also comes at the cost of well writing a lot more code especially having to deal with this but when it comes to working with state i think a class makes it easier to work with state as opposed to a function component so unfortunately it really comes down to one personal preference and two whether or not the class or the function fits the component and the more experience you have developing react applications the more you will be able to reach for whichever option the first time the primary way that we get data from the user is through forms and with just plain ordinary vanilla javascript working with forms can be a very tedious process and unfortunately with react it can also be a very tedious process but it really depends there are two different approaches and we're going to look at both of those now form controls and when i say form controls i mean the elements that we would use within a form like an input element or select or text area those kind of things a form control as far as react is concerned has its own built-in state and the difference of how we approach working with forms really depends upon how we are going to work with that state so in this lesson we are going to look at something called controlled inputs which is probably well there's no probably it is the most tedious approach to working with forms however it's also considered the quote-unquote correct approach and we are not going to use our counter we are going to use our list but we're going to take some time and we're going to convert the list into a class just for first of all the sake of practice because as with every skill practice practice practice makes you better at that particular skill and two we are going to be working with a more complex component now the list is rather simple yes however when we're done with it at the end of this lesson it it's not going to be so simple and really quite frankly it's going to be the wrong approach and the reason why i want to show you the wrong approach is because i don't want you to make the same mistakes that i did and that everybody else did when starting with react because there is a wrong way of doing it and so i think it's helpful for you to see that wrong way so we want to import first of all component from react we also need our list item don't we let's open up list so that we don't forget anything and we can just copy and paste this we need to in fact let's put the list on the right hand side because that will make this a little bit easier to manage here so we want to import the list item i'm not necessarily concerned about the prop types so we're going to leave those alone and we want to define our class we'll call it list it's going to extend the component class and from the previous lesson you know that the first thing that we should do is define our constructor so that we can call super and then pass in the props we're not going to worry about state just yet and really the only other thing we need is the render method which as you learned in the previous lesson is essentially the function in our function component but of course we need to make a few changes because since we are going to be inside of a class we need to use this all over the place so props dot items becomes this dot props dot items uh the css was fun let's get rid of it and then props.title becomes this.props.title so with that change we should be able to just specify the list class file let's go to the browser and export defaults yeah i always forget the export statement always you would think that i would know that i need to do that because i always forget it but no that's not the case and so here we have our list so everything's working fine as far as the component is concerned so now let's add in a form because we want to modify our list so let's put this form inside of a div element let's add some padding to the top as well as the bottom and we'll only have two elements we'll have just a simple input element this will be where we of course put in the guitar name that we want to add to the list and then we will have a button so the idea will be that we will enter the text we'll click on the button and by clicking on the button we will then add that text or that guitar to our list so we'll have button and we'll use the primary class and as far as the text is concerned we can just have add guitar so let's make sure that looks okay it doesn't but that's going to be okay and we can close out the old list now now without knowing anything else about what we need to do we know without a doubt that we need to do something whenever we click on our button so let's go ahead and let's define that on click event we'll say that we have a method called simply handle click and we can go ahead and define that although we do need to say this dot handle click so let's define that method we need the event object because we want to prevent the default action of occurring which is submitting the form so we want to prevent that from occurring and then we want to add the text to the array now we also know from the previous lesson that we need to do some trickery so that our handle click is going to execute within the context of our component class here so let's do this inside of the constructor to where we say this dot handle click equals this and click bind so there we go and now the question just becomes how do we get the value from our input and in just traditional javascript we would probably assign this an id so that we can get a reference to that element object so that we could get the value of the text box and we will do something similar in a future lesson for now though we're going to use this as a controlled input what that means is that we control this input through our code the user does not control this input so the first thing that we need is our state so let's go ahead and let's define our state and we want a value that we can use for our input element so we could just call this new guitar let's initialize it as an empty string and then we are going to set the value and we are going to use that new guitar from our state let's put these attributes on multiple lines because that makes it a little bit easier to see so by doing this we can go back to the browser and i'm going to start typing hopefully you can hear my keys nothing's happening because we are controlling this input that means that not only are we providing the value to it but we also have to update that value as well and we do that with the on change event so let's define that and we'll just call this handle change we need to define that method we can copy our handle click and of course change the name but we also need to do the binding in the constructor so that we can get around any issues with this and so inside of handle change we want to take the value from the input element which we get from the event object we get the target property followed by value and we want to change our new guitar in our state so we will call the set state method we want to update new guitar with the value from the form field and this is where the tedious part comes into play because whenever you use controlled inputs within your form if you want to work with those values inside of your code you have to first of all set the value of that input which is typically something from state and then you have to handle the on change event so that when the user types something into that field it automatically updates the state which then updates the value of the input so if we go back to the browser and we type in here we can see that we have a value so now when it comes time to actually handling the click event on the button we have the value that we want to use which is that new guitar so we can go ahead and we can grab that from our state but then we need to update the items prop now remember that props are read only not only do we not want to change the props we can't change the props so something we could do is add state here we could add an items to our state which we could go ahead and initialize as the items from our props so that whenever we click on our button we get the new guitar from our state and then we will set the state for our items where we are going to take the existing value and we want to spread those out into this new array and then we want to add in the new guitar now that means inside of render we need to change this from using our props we want to use our state everything else though should be okay so if we go to the browser and we type in flying v and we add that guitar we can see that it is being added to our list if we want a vella then once again we can add that to our list let's do this though whenever we click on the submit button and we add the new item to our array let's clear out that text box so we're going to set state again to where new guitar is an empty string so now if we come back flying v add guitar there we go we have a better experience already so this works however this is not the best approach in fact i would say that this is the wrong approach to take for a couple of reasons for one the list itself really should only be responsible for displaying the list it should not be responsible for making changes to that list and while in some circumstances you will want to take values from your props and use them in your state in this particular case i'd say that no we don't want to do that at all so what we want to do then is what we typically refer to as lifting state we want to lift the state out of this list component into the parent but in this particular case i don't even think we want to necessarily do that i think we want our guitars listed here but i think what we want to do is have another component we could call it simply add item this add item component would have our form and we could have our own on submit event so that when the user clicks on that button we execute whatever was provided for on submit which is essentially our own custom event which will then modify our array and then those changes will flow down through the list and the items props so just to briefly recap on controlled inputs a controlled input is one where we control that input element we provide the value and then we update that value with the onchange event and for every form control that we would want to interact with we would have to do the same thing which is why this is the tedious approach in the previous lesson i introduced you to the concept of controlled inputs it's an input element or text area or select or anything that we would use inside of a form they have their own built-in state and we essentially control that state by providing the value for that component and then changing the value and it is quite frankly a tedious way of going about it but it works and it is the quote unquote correct way of going about it now in the midst of that we also rewrote the list component to be a class first of all for practice second of all so that i could show you what not to do because what we ended up doing is providing a form inside of the list component so that we could modify the list in the browser which is a nice little feature to have but really we should be adopting the principle of single responsibility all of our components should be responsible for one thing so our list component should just be responsible for displaying the list and nothing else but also part of this is because we've added state here where really the state shouldn't be inside of our list component we need to lift it out into really the app component and really we should write another component which we could call add item which will have our form and it will have a custom event called on submit so that whenever we click on that submit button it will provide whatever value was typed into the form field so that we can then update the guitars so let's get started by writing that add item component now since this is going to be dealing with state i'm going to opt to use a class once again because it's a good practice to do and really we can take the code from our list class and we can use this as a basis so really what what are we practicing i don't i don't nothing apparently there are of course a lot of things that we need to remove like for example we don't need the items in our state uh we need the handle click and the handle change and we don't need any of the markup that's going to display the list so we can get rid of that and we can get rid of line 34 where we create those items and really let's change our button text let's make this a prop because we want to make this generic so that we could use this really for anything so we'll have a prop called button text so we'll need to remember to provide that let's change the name of this to add item and then let's export this so that i don't forget to do that finally all right so our states our new guitar let's call this new item and we of course need to change that every other place which thankfully visual studio code highlights the usage of those identifiers so that we can easily spot where they're being used and then change them and that should work we do need to import this inside of app so let's go ahead and do that and let's not use our list class let's just use our list because that makes a lot more sense the list is a very simple component it is simply displaying our list of things now of course we'll probably get an error because we didn't supply anything for on submit all right so now when it comes to our custom event here this is nothing more than a prop that's all it is we provide a function to this on submit so that inside of add item all we have to do is execute that function and we want to execute that inside of our handle click that is whenever we are clicking on that button so we still want to prevent default we don't need to set state for items because we don't have items we do want to set state for the new item because we want to clear out that text box but we want to call the on submit function we'll pass in the new item and really let's just get rid of that variable we don't need it and there we go that's it all a custom event is is a prop that you provide a function for and then inside of your component you just make sure to execute that function wherever you need to so very very very simple all right so that should work for that let's go to our app component and we need to supply a function for on submit so the first thing that we can do is write a function we'll call it update guitars so that we will get the new guitar from that component and then we will modify the guitars array so since we have that function we can go ahead and specify that now the question becomes how do we update our array now remember that we want react to automatically re-render the page whenever we modify our list of guitars we need to supply the button text so let's do that uh we'll call this ad guitar and so just changing the value of our array isn't going to tell react that it needs to re-render it only re-renders when state changes so we need to change this to state so first of all we need to import use state so let's go ahead and do that and then we will use state to create our guitars we will have the function called set guitars and we will go ahead and use this array as our initial value i think eventually what we would want to do is just have an empty array so that we could add whatever items that we wanted to and then inside of update guitars all we would then need to do is call set guitars where we would set the new array we would take the existing guitars array but we need to spread that out and then we would add the new guitar there and that should work so let's give it a whirl so if we want a flying v we can add a flying v if we want a vella we will add the vela if we want a telecaster we can add the telecaster okay so to recap we lifted our state out of the list class component and kept it inside of app because really that's where it should be to begin with the app component is supplying the information to the list so that list is responsible for just displaying the array of things we wrote another component called add item that has a custom event on submit so that whenever the user types in something into the input element and then clicks on the button that executes our onsubmit event it passes the new value to the event handler and then we update the state well in the next lesson we will talk about uncontrolled inputs it's really easier to work with however it is a more controversial topic over the past couple of lessons we have been using controlled inputs when working with a form because that is the preferred way of working with forms in react the reason is because it uses that one-way communication you know from parent to child and i know what you might be thinking well what about the communication from child to parent because that's kind of what happened whenever the child executed the on submit prop yeah but it's still apparent parent-to-child thing because the parent supplied the on submit prop to the child and all the child had to do was execute it pass in the information that it was expecting and that's it so all of the work was being done inside of the parent so it's still that one-way communication now there are some issues with using controlled inputs for one it's a little tedious because if you have a large form you have to manage the value and set up the unchanged event for every form control that you want to track for large forms that's gonna take a while but more importantly there's just some things that you cannot do with controlled inputs like for example if you wanted to focus the text box after you add a guitar you can't do that now that might not seem like a big thing but if we are writing software for data entry we want to empower the users as much as possible so that they don't have to do a lot of tabbing to the correct form control or moving the mouse to provide focus we just want them to type in or type in our type inner type enter we write software to empower users so if we can't provide that functionality with controlled inputs well we can with uncontrolled inputs so that is what we are going to look at in this lesson i'm going to change the title here i have not been doing that and i apologize for that but at least for this lesson we have uncontrolled inputs and we are going to make a few changes because i want to use not just a text box but i also want a select box so that we can provide the name of the guitar as well as the maker so that we have two pieces of information we can work with two form controls so this means our data that we are working with needs to change because it's no longer going to be just a simple string we're going to have an object and since our list and our list item components are generic and we are supplying information to those components we are going to have generic properties for these objects so the title is going to be the name of the guitar then we will have a text property that will be the maker and this means we need to make a few changes inside of list because when we create these list items we're using that text prop that doesn't make a whole lot of sense now so we're going to change that to item let's also get rid of the css for our list title because that's just ugly it was fun but let's move on and then for our list item this is going to be a little bit different because we still have a text prop but it is just for text but really it's not a prop it is a property of our item prop so we need that and let's put the title inside of an h5 so we will have the title there and then we will just have the text underneath that so in the browser we shouldn't see that much of a difference the text looks a little bit different but that's good so we can close that i believe we can close our list all we need to really do is focus on our ad item okay so when working with uncontrolled inputs you do not use state so our only state value was that new item so we can just get rid of state altogether which means that we can also get rid of the handle change because we aren't going to be needing to listen for the change event we still need to be able to listen for the click event on our button because that is going to signal that we are ready to add that new information so inside of handle click since we don't have state there's nothing to set so we will get rid of that we still need to execute our on submit prop though so we will leave that we don't have handle change at all so we can get rid of that and we don't need the value or the unchanged props for our input element so that's great i do want to add some markup here since we're going to have multiple fields uh let's have some separation here so we're going to have two div elements with some bottom margin and we'll put the input element inside of one of those and then we will put our select element inside of the other and for right now we're just going to hard code the data for our select element later on we're going to emulate server communication such as we would be contacting a server application to get our guitar makers so that we could then populate this and we're going to have a few options the first is going to be empty because we don't necessarily need to specify the guitar maker because there are some guitars that aren't branded at all and then we'll have three others so our first one is going to be prs the text will be prs in fact the text for all of these are going to be the same as the values so we will have prs fender and gibson and when that is done we can go back to the browser let's make sure everything looks okay our button or rather our select needs to be inside of that div element there we go there all right so now that should be okay that's okay that's better all right so now we just need to get the values of the input and the select elements whenever we click on our button and we do that by using refs we are going to create a reference for each one of those form controls so that we can get their values it's going to be very reminiscent to just vanilla javascript you know where we would assign an id attribute and then we would get that element by its id and then get the value it's very very similar so to create a reference we need access to react so let's just import react we'll change our class to extend react.component and then we will create our references we need two of them one for each form field that we want to work with so let's call the first one guitar name and we're going to call react create ref and we pass in null as the argument this is going to create a reference for our input component and our select component and we will assign these refs as well because each one of these components has a ref prop to where in the case of the input that's going to be the guitar name and for the select that will be the guitar maker and we will use these refs to get their appropriate values and we will do that inside of handle click so let's use the terminology that the app component is going to expect so that is the title and the text so the title is the guitar name we use that guitar name ref now remember that we are inside of a component and we could have as many of these ad item components inside of app that we want so this means that we could have a lot of these input elements inside of the same page so react needs to know which specific input component that we want which is the current one makes perfect sense and once we have the current one we can get its value we will essentially do the same thing for our select so let's use the guitar maker will change the variable to text and since we need an object now we're going to pass in an object with the title and the text so this is the basic functionality this should work let's add vela which is prs and we want to add something doesn't work so let's take a look at the console and see what error we have cannot read properties of null reading value that is inside of the add item line 19 so guitar maker current value let's highlight this okay so that's good that's good makers that needs to be maker all right so now this should work we want to add vella that's prs and we want to add there we go we can see that that was indeed added let's add the telecaster which is fender and add so i'm using the keyboard now and it would be nice to go ahead and focus this well not just focus it but let's also clear it out would be nice to also clear out the select box so let's go back to our handle click and let's do just that so after we call the on submit prop we will first of all set the guitar name value to an empty string then let's call focus and actually let's do this let's set the guitar name and the guitar maker's value to an empty string first and then we will focus the guitar name that way we don't run into anything weird i mean we shouldn't have anyway but you never know so let's do a refresh start completely over let's add vela for prs let's go to add there we go telecaster for fender let's add flying v for gibson and if we had a guitar that we have no idea who made it we don't have to select any maker we can add guitar and it still works now i should say that refs are controversial there are some people that say no you should not use refs at all however they do provide an actual use just be careful when you use them if you need direct access to what is essentially the dom object really you're accessing the component itself but when you need that level of access to automatically focus something or to select the text inside of a text area or a text box or anything like that then refs make perfect sense if you have a very very very large form refs make sense but if you don't need any of that functionality if you have a relatively small form i do recommend you use controlled inputs because it is the preferred way of working with forms it's been a while since we've talked about css and really the only thing that we talked about was adding a css file to one of our javascript files using import and then that css file and that adds the css to our application and it is globally accessible so all of the css rules inside of that file or files are accessible inside of all of our components that's fine however there are some times when we might want a little finer control like for example if we wanted to use inline styles now i know red flags are probably flying up in your head inline styles well that's evil we've learned that we'd never use inline styles and yeah but this is a different programming paradigm we are in react and we have tools that pretty much negate anything that we have learned over the many years of web development so if you're not familiar with the term inline styles it's basically just using the style attribute so let's just imagine that this li element is html it has a style attribute where we would supply the css properties that we would want to apply to that element so if we wanted to set the background color to red then that is what we would do if we wanted to set the foreground color we would add that css property and its value it's very straightforward however this is react we are working with react elements and components and this li component doesn't have a style attribute it has a style prop where we provide a javascript object that contains the css properties that we want to apply so if you've ever written just plain vanilla javascript where you set the style the inline style on an element using the style property and you have the camel cased css property name and then you assign it a value that's essentially what we do inside of the object that we pass to the style prop so in this case if we wanted to have a background color of red then it would look like that just normal javascript css stuff and if we wanted to have a foreground color of blue then we would just add another property to this object called color then we would supply the value blue so let's apply style to this li element based upon the guitar manufacturer so let's create an object called maker styles and the properties of this object are going to be the values of prs fender and gibson so that we can match that with the maker that is being passed as one of the props you know it's that text prop so for prs let's say that we will have a foreground color of gray and then a background color of yellow it's going to look ugly but i want something that is going to be a visual so that we can definitely see the difference between these things so we have prs we have fender and then we have gibson so for fender let's set the foreground to red let's set the background to black and then the gibson is going to have white text on a blue background let's make it navy like navy better than blue and we want to apply this to the li element now remember that some guitars aren't going to have a manufacturer so we need to take that into account but we could very easily do that let's first of all create a variable because since our property names in this maker styles is lowercase we need to take the items text from our props so let's just create a variable called maker where if we have that text we will then lowercase that text so we will call to lowercase just like that so that's inside of our style prop we will kind of do the same thing so that if we have a value for maker then we can use that as a property for our maker styles so let's give that a try let's go to our browser let's say that we want to add a vella and that's prs so there we go we can see that we have a guitar with the styling for prs let's do a telecaster which is fender and we will add that and we can see that that's working but let's also say that we want to take these same styles and we want to apply it to the options in the drop down so one of the ways that we could do that is of course to just copy and paste that's horrible because then that's getting into the realm of why we don't use inline styles in just traditional html what we can do is actually just create a javascript module that's going to contain these styles that we want to use and then we can import those in whatever files that we need and we're good to go so let's create a new file we'll call this guitar styles dot js and we are going to export our maker styles in fact let's just go ahead and let's copy that let's actually cut it out because we won't need it here because we are going to paste it right there so we're going to export multiple things from this file so if we wanted to do the same thing for the types of guitars you know we could have a guitar styles that we could export and so that we can import either one of these or we can import both of those if we needed to but for right now we just need the maker styles so we can import that maker styles and it's just a javascript module so we have imported this stuff before and that is from the file of guitar styles so that now instead of this makers well yeah we still use that maker styles so uh we want to essentially do the same thing inside of the add item component so let's import our maker styles inside of add item and then we want to apply these styles to our options so that once again we will have our style prop and we want the maker styles dot prs for this option then let's just copy and paste make the necessary changes so that we have fender and then finally gibson so whenever we go to the browser now let's add the flying v whenever we click on the select box we can see that the options are going to be styled the same way that the items in our list are styled based upon the manufacturer now of course yes you can accomplish the same thing by creating a css file putting in those same css classes and you're good to go but this is just another option that's available to you so if you don't want to use css classes for whatever reason you can use javascript one of the benefits of using create react app to create your project is that you get css module support out of the box now if you're not familiar with css modules well it's just css there are some differences between a regular css file and a css module but it is still css now one of the big features is that you can scope your style to whatever file that you want to use those styles in so whenever you import a css module it is not globally available it is only available inside of whatever component you import it into so in this lesson what i want to do is temporarily mind you change the text of the navbar brand i want to make this bold and yellow and it's going to be ugly which is why it's going to be temporary so the first thing that we need is our css module now the first part of the file name is not magic since this is going to primarily be used inside of the navbar component i'm going to call it nav bar the magic part of this is that the end of the file name has to be module dot css because that is what is going to tell the compiler to handle this file differently than just a regular css file so let's define a class that's going to have bold yellow text and we can call it just bold yellow text now notice the style that i used for this class name it's camel case you will see why here in a moment but let's set the font weight to bold let's set the color to yellow and we better mark that as importance because bootstrap will probably override that so we have this class name that we want to use inside of our navbar so let's go ahead and let's import that the big difference here is that we aren't just going to import that navbar.module.com we are going to also import an object so import styles from and then our file name now styles is just convention probably in most projects you will see styles used so you can use whatever you want the convention is typically styles and we want to use that bold yellow text class for the class name for our navbar brand so we're going to start by just using a javascript expression styles this is an object and we have a property called bold yellow text so this is why i named that class name using camel case because the classes that you define inside of a css module end up being javascript properties so let's save this go to the browser we see bold yellow text for our navbar brand but we also want to include the navbar brand styling so we can use string concatenation so that we will have our navbar brand and then we will bring in the styles dot bold yellow text and in the browser we will see both of those classes being applied to that element now let's inspect this because whenever you use a css module and the classes are scoped the way that it becomes scoped is the name of the css class it doesn't create a class just called bold yellow text it is somewhat unique now we could take this css class and we could use that in other files but why would we want to do that if we wanted to use this in other files then all we would need to do is import this file into wherever we wanted to use it so let's say that we wanted to do this inside of app because we want to not just have the container but we also want this to be bold and yellow so we will add the styles and then bold yellow text so it's not limited to any file the only stipulation is that we have to import this module wherever we want to use it and so there we have our bold yellow text but let's say that okay this is a style that we are going to use in multiple places throughout our application it makes sense to make this global so that we don't have to import this file wherever we need to use it well we can mark this as global by using a special command beforehand it's colon global and then we have our class definition and this is going to generate an actual css class called bold yellow text so we will be able to use this throughout our application wherever we need to without having to import the file so let's actually back out those changes because that's easier and then we can add bold yellow text and whenever we go to the browser we see that that is indeed what we get but notice uh we lost that styling for our navbar brand so because that class is global we no longer access it through that styles object that we are importing we simply specify the name of that class bold yellow text and that is going to solve that for us now there's another feature that css modules have and that is the ability to compose your classes based upon other classes so let's say that that's great and all but i'm lazy i don't want to have to specify navbar brand space and then bold yellow text i want a class that combines those two together and we can do that inside of our module we're going to define another class we'll just call it my navbar brand and there's a special command called composes to where we can specify the classes that we want to use to compose our own class so we want to use bold yellow text but since this is global we have to say from global if it was a local class then all we would have to say is just the class name but that's not the case this is global so we have to specify global but we also want to compose using the navbar brand class from bootstrap but here's the issue we have to specify the file where this class is defined and that is inside of node underscore modules slash bootstrap slash dist slash css bootstrap.min.css that's a a lot to type so if you want to build your own classes using bootstraps classes you would have to have a composers statement for every class that you want to use so you can't have composers and then navbar brand space bold yellow text or anything like that you use composes you specify one class and if it is not local to this file you specify where it is coming from so that can be rather tedious but this is going to give us my navbar brand so that inside of navbar we can get rid of these two classes and we can use our styles once again we'll say my navbar brand and we will end up with the same result visually but if we take a look at the css class that is generated it is now well it's different so css modules are another way that you can add style to your project it's especially useful if you want to scope style to certain components and it also gives you the ability to define global classes as well as compose your own classes based upon other already existing classes we write applications in order to work with data and for the vast majority of those applications the data resides well outside of the application so that means we need to load it we are loading it from web services from local storage i mean there's a variety of ways that we can load data into our application and sometimes it's not very obvious as to when we do that so what i had originally planned was to load the guitar manufacturers for our ad item component so that we could pull that data dynamically and then your application would use it but no i want to do something completely different something that's actually usable so we are going to write a weather widget we are going to fetch data from an actual web api and use that in a component that we can then just drop into any application so it is going to be self-contained in fact the only thing it is going to be dependent upon is the location to retrieve the weather that's going to be the prop so it is going to have its own state it's going to make its own http requests it's not going to be dependent upon anything else other than that location prop so we are going to write two things in this lesson the first is going to be the weather app and we are going to use the weather app inside of index so instead of using this app component which is what we have been using we are going to use this weather app let's go ahead and import that even though it doesn't exist just yet and we are going to use it right here so weather app and the weather app itself is going to be a function but it is going to have some state so let's go ahead and import use state we're also going to use a ref because we are going to have a form that the user can fill out for the location now we aren't going to use a controlled input because a controlled input is going to update state every time the user types into the text box i don't want that i want the state to change only when the form is submitted so we are going to use a ref so that we can reference that input element and whenever we click on the button that will change our state so let's call this weather app and let's go ahead and define our state so that is going to be the location then we will have our function to set that location and let's set this to an initial value of an empty string and we can go ahead and create our ref now that i have told you why we are going to use a ref and this is one of those reasons why we would want to use a ref we want specific functionality that we can't get from a controlled input so we're going to use a ref in this case and then we are going to have our jsx now i'm going to paste this in because it's quite a bit of markup but there's nothing really special about it it's a div that contains a div that contains a div that has a form the form has an input element and it has a button so since we have this input element here let's go ahead and set up the ref with that location input and then our button we will write a function to handle the click event which is going to update our state and then there's this weather widget we do need to export this so let's export default weather app this does not exist yet but it will here in a second so let's go ahead and import weather widget from and that file is going to be weather widget class because we're going to write this as a class we're also going to write it as a function because how you load data is different between those two different types of components so let's go ahead and let's create that new file we'll call it weather widget class and let's go ahead and import components i don't think we need really anything i mean we are going to have state but this isn't going to accept any user input at least as far as the ui is concerned that is going to be supplied as a prop so we should be fine with just importing component here then we'll call this weather widget and it is going to extend the component class let's go ahead and write the constructor where we are going to have our props and we're going to pass those on to our super class and then let's export the weather widget so that we do not forget to do that let's also go ahead and define the render function and for right now let's just return a div element i want to see what this is going to look like in the browser make sure that the form looks okay uh whether which it is not defined it is except that we need to save that file so now we have our form that that's that's great now we are going to approach the development of this widget a little bit differently because the web api that i'm using is called weatherstack they have a free subscription but you are limited to only 250 requests for the month so we need to be a little bit stingy with our requests and one of the ways that we can do that is by changing uh inside of index if we get rid of the react strict mode because as we are developing our application while we are in strict mode the render method on a class or the function component executes twice i don't know if you've noticed that whenever we've had the console open but that is because we are in development using strict mode if we were to build it for production and then run it we wouldn't be seeing that behavior but since we are limited on the amount of requests that we can make we need to be a little stingy with those requests so at first we aren't going to be making requests we are going to set up our application to make those requests but we're going to wait to actually send those requests so that we don't use our quota uh so our button in our weather widget let's set up the on click event we'll call this handle click and let's go ahead and define that function so that whenever we click on this the first thing we want to do is prevent the default action from occurring which is submitting the form and then we want to set our location to whatever was supplied here so that is going to be our location inputs value so we need current and then value and as far as the app itself that is essentially it because all of the work is going to be done inside of our weather widget and as far as the app component itself that's it it's relatively straightforward all it is doing is getting input from the user so that it can supply that to the widget so in the next lesson you will learn how and where to load data within a class react is a framework for building user interfaces that is its primary purpose so the purpose of every component is to build a small piece of that user interface and that's all well and good however as you were writing an application that's really not feasible because an application is working with data it's got to interact with that data by either pulling it from a web service or reading it from the browser's local storage it also has to update that data by issuing other requests or saving it to local storage there might be some logging that needs to occur there might be some caching that has to be written there's a lot of things that an application does other than just displaying the ui so for all of these other processes that occur we call those side effects and a lot of our components are going to be working with those side effects however there are some good places to do that there are some not so good places to do that like for example the constructor the constructor is for initializing the things that the class is going to need like for example we need state for this because we need to store the weather data that's going to come from the web api so initializing our state in the constructor makes a whole lot of sense however issuing the request to that web api inside of the constructor doesn't make a whole lot of sense primarily because if you make a request you might want to cancel that and you can't necessarily do that inside of the constructor so anything other than just straight up initialization is not really suited for the constructor so then i want you to think about just a typical web page no frameworks no nothing just vanilla javascript and the tools provided by the browser so a lot of times we want to do something after everything in the page has been loaded so that's when the load event occurs within the browser and inside of our components we have something very similar it's called component did mount this is essentially the load event for our component this means that the component is loaded in the browser everything is there the dom's there and it's ready to do whatever it needs to do so in this component did mount event this is a great place to issue our request now we're not going to do that we're going to simulate that for right now so that we don't work against our quota for the web api but let's just write something to the console that says request made in components did mount it's a bit verbose but it's clear let's also write a message in the render method so that we know that render occurred so let's go to the browser let's refresh the page and we are going to see that render occurred so that's what first happened and then we can see that a request was made and component did mount so it's great that a request was made because that's what we told it to do however what did it request because there was no information provided we definitely didn't click on the get button so the request was made for no location whatsoever so really what we need to do inside of our component did mount is check to see if we have a location from our props and if we don't then we of course don't want to do anything but if we do then we will issue that request so let's save that let's go back let's refresh the page we're going to see that it rendered which is good render occurred but notice that the event didn't occur we did not issue that request and that's really good so if you have the react developer tools let's go to the components tab let's take a look at the weather app and we can see that we have some states there is nothing there it's an empty string we have our ref and if we look at the weather widget the props the location is an empty string okay that's all well and good that's as it should be so we are going to request the weather for dallas so we click on get we can see that the state for the weather app changed that's dallas we can also see that the location prop is now dallas but if we look at the console it rendered because the props that were sent to our weather widget component changed so therefore rendering occurred but notice that we didn't issue that request that's because this component did mount this is a one-time deal this is when the component is mounted so it's not going to execute every time it renders it's only going to execute that one time when it is mounted so in that case we want to tap into another event called component did update and this has two parameters the first is the props that were in the component before it was updated so it's called previous props the second is the previous state so if we need any information from before the component was updated we have that information now i lied there's actually a third it's called snapshot because there is this component did update but before this occurs we could actually tap into another method that gives us a snapshot of that component before it has been updated in the dom and and everything like that we aren't going to really worry about that because in our case this is going to be sufficient for us so essentially what we want to do is make sure that the location is different from the previous props to the current props and the reason being is remember that we are limited on the amount of requests so we need to put a governor in this thing so that we don't make a whole lot of requests so if the location prop doesn't change so if we type in dallas and we click get 10 times we don't want to issue 10 requests we only want to issue one because there's no need to do those other nine well because it's the same location so what we're going to do here is use the previous props and we're going to check to see if the location is different than the newly provided location prop and if it is then we are going to log that the request was made or let's say request made in component did update now we could take this a step further and track the time of the last request so that if the location hasn't changed but let's say that it's been more than a minute from the last request because you know the weather changes that fast then we could issue that request and that would be relatively straightforward we would need to track the state and the time and all of that stuff but we're just going to keep things a little simple here all right so let's take a look at this now let's refresh and whenever this loads we see that the render occurred that's what we would want if we click on the get nothing happens because no data is changing at all so let's provide dallas for the location we'll click on get and we can see that the request was made in componentdid update that's exactly what we wanted if we click on get again nothing happens because the data is not changing let's change it again and of course we see that a request was made so this is the functionality that we are after now you might be asking yourself that's great but why did we do the component did mount because as it seems right now we're not using that but remember that we can supply a value for location just right out of the bat let's go to the weather app and for our default value for the state let's just put dallas there so that whenever we refresh this we're going to see that a request was made in component did mount so the reason why we're doing it in component did mount and component did updated so that we can cover both of those bases so that if we have a location at the very beginning then we will go ahead and make that request otherwise whenever the data changes we will make our request then so as far as our class is concerned i think we are good to go we aren't going to proceed just yet with issuing our requests because in the next lesson we need to look at how to do this same exact thing inside of a function component in the previous lesson we talked about side effects and where we want to do those effects because we don't want to just issue an http request anywhere like the constructor is a very bad place to do that we probably don't want to do that inside of render either we do however want to issue a request when the user does something to initiate that like clicking on a button or if we want something a little more automated then we want to use a life cycle event like the component did mount which is essentially the load event for a component and then there's the component did update which well it executes when the component updates so we want to replicate that same functionality inside of a function component so let's go ahead and let's create that file we'll call it weather widget function and let's just copy what we have from the class and let's use that as the basis for our function because we it gives us quite a bit so instead of importing components we can import use state because we do need state so we can go ahead and set that up we called that data inside of the class so we will have data and set data and i believe we initialize that as no now of course we need to change this so that it is a function and we want our props and i'm going to go ahead and do this i'm going to destructure our props so that we can get direct access to the location because that's what we are after for the most part and that keeps us from having to type props dot location all of the time and then we have our render which well that is essentially our function so there we go we have our function so let's modify the weather app so that we are going to use our function instead of the class let's also change the default value here instead of dallas we will have an empty string so that inside of the browser looks like everything works let's refresh the page and we should see that the render occurred so there we go whenever you want to use side effects inside of a function component you have to hook into react just like we have to hook into react to use state so we have a hook called use effect and the first thing that we pass to use effect is a function that we want to execute this is essentially the effect that we want so what we want to do is make an http request so we will write to the console request made now remember that with a function component the function is essentially the render method so this function is going to execute for every update so whenever we see this in the browser our effect is going to execute every time so just by loading we see that render occurred and then request made if we change the value of location render occurred request made if we change it again that same behavior is going on so that kind of looks like the behavior that we want in fact really the only thing that we should be able to do is just check if we have a location and if we do then we will make the request otherwise we won't and yeah that could get us there that could do more than get us there that would get us there however i think that there is a better option because you can pass a second argument to use effect which is an array of values that the effect is going to be dependent upon and that that's not really a good description it's an array of values that could change and if they do change then we want the effect to execute now if we pass in just an empty array we essentially replicate the functionality of component did mount so i'm getting rid of the check for location so that the first thing that happens whenever we reload the browser we can see that the render occurred and the request was made but if we change the location the only thing that's going to happen is it will re-render the request is not made so the effect that we wanted only executed when the component was loaded which is essentially the component did mount so if you need to replicate component did mount inside of a function component you can use effect and then pass an empty array as the second argument but that's not what we want we want our effect to essentially occur every time that location changes so we want location as a dependency here and once again we want to check if we have a location before we try to make a request so with that little simple change we should see the behavior that we want so the first loading the render occurs there is no request made if we have a location the request is made if the location changes once again the request is made so this is what i would argue is what we need for our purposes because we want this effect to occur when the location changes now that means whenever we set data you know that is setting the state that is supposed to trigger react to re-render our component which in the case of our function component it will re-render it by executing this function but since we have said that our effect is based upon the location the effect is not going to execute if we wanted it to execute when data changed we would need to supply data as a dependency so this is why i think that this is the better option because if we don't supply any dependencies it's going to execute every time and we don't want that so in a way this is very much like what we did in the previous lesson inside of componentdid update where we are checking if the previous props location is not equal to this props location because this component can update for a variety of reasons it can update because we have changed the state in which case we do not necessarily want to issue a request we only want to issue a request when the location changes so in the next lesson we will implement the rest of our weather widget we will make a request and we will display that information in the browser well we are finally ready to finish our weather widgets and we're going to start with the function component since we talked about that in the previous lesson and i'm going to start with the markup so that we can get everything ready to display the data and then we will make the actual request because we are limited on the amount of requests that we can make so our div element is going to have a class of card so we are going to use the card from bootstrap in order to organize this that gives us the ability to display an image that is representative of the weather at whatever location we specify and we are going to need another div for the card body because this is where we are going to have the title which is going to be the location name now you don't have to worry about the structure of the incoming data because i already know that so we have the data that is our state so that's going to be our entry point into this it's going to be a little bit of typing but for the name it's going to have a property of data.location and then name and then outside of the body we are going to have an unordered list but we are going to make this a list group and we're going to display just some information about the weather at this current location like for example we will have the temperature that's kind of important so let's just copy this and paste it a few times so we will have the temperature which is going to be data dot current and then temperature and there's also going to be a description there could be multiple descriptions but we just want one and it's going to give us just the the basic information like if it's cloudy or partly cloudy or sunny or things like that so that is also inside of current and there's a property called weather descriptions this is an array and we're just going to pick the first item out of that array we also want the wind speed because wind is important that's also in the current section of this object and wind speed uses the underscore naming style as does the wind direction because it's not good enough to just know what the wind speed is you kind of need to know in which direction it's going and then finally the humidity i used to not care about humidity but then i lived in the houston area and um yeah i went from a very dry area to a very humid area and i care about humidity now so that's the information that we are going to display and of course if we were to view this inside of the browser it would not work in fact we probably have an error yeah we do because none of this stuff exists yet although let's see here undetermined regular expression uh we need to close out that so that we have a closing curly brace all right so we have everything ready to display although one thing we should do uh let's get rid of this console log and let's do this if we don't have data then that means it's still going to try to display some of this information and we could run into errors so if we don't have any data then let's just display nothing and that's going to be just fine all right so now it is time to make our request so you can use any http library that you want i like fetch it's easy enough to use and i'm going to paste in the url that we are going to be using so we are going to hit the weather stack api we want the current because that's one of the few things that we have access to as a free subscription so this is going to give us the current temperature at whatever location we specify and i'm using fahrenheit for my units because i'm in the us and of course you need an access key so if you want to follow along and build this yourself you will need to sign up for a free subscription to get your access key there is this access key that you see on screen that's going to change so it's not good enough however to make our request we then want to do something with the response and that is to convert it from the json structure into a javascript object and then we will take that javascript object and we will set our data passing in object so there we go that is our widget that should work let's save it let's go to the browser uh looks like we have some errors but let's just refresh and let's see if those errors go away looks like they do all right so let's get the temperature uh you can put in whatever you want i'm going to do dallas and oh we need the image don't we yes so our image is going to come from the weather stack api so we are going to set the source of this image to data current weather icons and there may be more than one there's always going to be one so we are going to use that first one so now with that in place we can see that it looks like it's a clear night the temperature is 70 degrees fahrenheit wind is 4 miles per hour out of the northeast and the humidity is 42. that's high but it's not going to be as high as houston so if we take a look at houston temperature is 75 it is overcast which yeah and the wind is 6 miles per hour east southeast humidity 88 i'm glad i am not there all right so that is our function component we have this widget so we could if we wanted to we could take this code we could lift it out put it in any application and it would work the only thing that we would need to supply is the location so it is completely and totally on its own so let's go to the weather app let's change this so that we are going to use our class and there's going to be a lot of copying and pasting so let's take starting from the if check for data all the way down to the end of the return statement and we're going to use that inside of our render and to make this a little bit easier what we'll do is create a data variable to where we will set that equal to the data from our state that way we don't have to change anything as far as the output is concerned but then we have the code for the component did mount and component did update now we essentially want to do the same things here we want to issue a request for whatever our location is so it would make sense to define a method let's just call this fetch data we don't need our location because our location is provided through our props so we can essentially take the same code of whenever we fetch information and paste that inside of fetch data we do need to change where we use the location that is coming from our props now and instead of calling set data we want to call set state and we want to update our data and i'm going to do this to make it easier so that all we have to do is say that we want to set our state and the data there so that should be fine except that we need to call this fetch data inside of component did mount we need to do the same thing for componentdid update so that should be it let's save it let's go back it should automatically reload with whatever data that we had there so let's do something else let's do san antonio i love san antonio so let's get that we can see that it automatically updated for us temperature 75 partly cloudy wind is eight out of the southeast humidity is 82 i believe that i love san antonio i do not love the humidity there and let's try new york just to see what that is going to look like new york is clear temp is 52 that sounds nice wind 4 miles per hour southeast humidity 48 that does not sound nice so there we go we have a working widget we have it both as a function we also have it as a class whichever way that we want to go after looking at the code i would say that the function is a bit more clean and clear as to what is going on but either approach gets the job done and it's not dependent upon anything except that location which makes it very nice and very portable so far everything that we have done every example has been just a single screen in a single page and there are many applications that are built that way an application could have multiple pages and on each one of those pages would be just a single component to do whatever that page needs and that's perfectly fine however there are many applications that are kind of the reverse to where there's a single page but the application running on that page has multiple screens so that you can navigate between those different screens and the best thing is that the page isn't reloaded you're not navigating to other pages we typically refer to these as single page applications and react was essentially designed for building single page applications but in order to have this functionality the first thing we need is called a router and there are many different routers for react the one that we want is called react router dom this is the router that runs within the web browser there is a router for native applications there's a router for server side applications that run on node and there are other routers as well but as i said for our purposes we want react router dom now i should say this is not part of react this is a third-party library however when it comes to building single-page applications this is what we use and it is very commonly used so we want to save this as a dependency now you might be thinking what exactly is a router well basically it takes a url and routes that to a component and this is a very common thing especially on server side frameworks where you would have a url that's incoming to the application the application would then decide what code is going to handle that url so it routes the url to the code that's going to handle it so in our case that code is just a react component so i want to make a few changes to our project because we're going to be creating a lot more files i kind of want to keep everything together so i want to take all of our existing code and i want to put it inside of a folder we can call that folder whatever we want i'm going to call it old stuff but there are some things that we want like for example we do want the index file we want the nav bar because it would be nice to have all of that ready to go for us so i am going to copy all of those files so that the stuff that we have right now is not going to be changed it's just going to be in a different place then i'm going to delete everything that we aren't going to need so we need index js and css we need nav bar we don't necessarily need the navbar module so we'll just leave that alone and we'll get rid of everything else so inside of index js we need to do a lot of cleanup now inside of index.js we're going to need to make quite a few changes first of all we need to get rid of all of the code that referenced any of our old components so that was the app and weather app components we also need to get rid of the weather app element now i'm going to keep the strict mode commented out because we are going to make http requests not for weather stack but we're going to hit a news api which still does limit us but we have a much better limitation i think it's a thousand requests a day so that should be ample but still i want to be safe and so in order to use the router we essentially need three things the first is the router itself which for our purposes we need the browser router except that traditionally what we do is it doesn't matter what router we use we want to call it just simply router so we're going to import the browser router as router then we also need the routes component because the router has routes and those routes have individual route so we need those three things and then whenever we render our application we are going to start with the router so then we will define the routes and then we define the individual routes so the first route that we will write is going to have a path prop this is the url so this is what is going to be inside of the address bar within the browser so a slash just indicates home it's the root of our application so basically what we see here localhost 3000. so we're going to have a slash for our path and then we get to specify the component that is going to handle that path and in this case let's say that we're going to have a home component so that's going to be our starting route and if we're going to have any kind of navigation between the components it kind of makes sense to have a second one and so we'll call this one just react and so the path for this is going to be react the idea being that this is going to display our react news and so let's create the home component so we'll just call it home and i'm getting a little lazy so i'm going to say export default function home instead of defining the function and then exporting it this is what i typically do and we want to return our navbar which we need to import and then we will have some content that just signifies that this is the home page which i think we had a div with the class of container and then we will just have an h5 that will have a title like home page something like that we do need to import navbar so let's go ahead and do that and let's copy this and let's paste it into a new file which we will call react news and of course we need to change the name of the function to react news let's change the text to react news page and then we need to import these inside of index js so let's do that but then we also need links we need a link so that we can click to navigate between these two components so it makes sense to me to put that inside of navbar because that is after all what its purpose is so after the navbar brand we will have a ul element with a class name of well there's going to be several so i'm just going to paste them in and then we will have individual li elements i have a class name of nav item and then we need to have a link now the links are not just your typical a elements instead what we need to use is a link component from react router so let's import link from react router dom and we will simply add the links to those components so the first is going to have a 2 prop this is where we want to go to which is going to be the home component now bootstrap's nav has a class name of nav link and then we will just have the text of home and then we'll just copy this and paste it for the react news we just need to make the necessary changes i believe we specified that the url was going to be react and it is and then the text will just say react news so with all of those changes we should be able to go to the browser and we get an error and that's because those things were exported as default okay so now we should see our page we have our navbar we are at the home page if we click on react news it should navigate us to react news now notice that the url is different but there was not an http request this was done just through javascript and the great thing is we didn't have to write the code to make all of that work react router is making that magically happen of course we had to set up the router but that's easy compared to this type of navigation so that's great let's add another page this will be for javascript news the component will be javascript news and we of course need that file as well but we are just going to copy one of the existing files and use that so let's copy react news we'll create a new file called javascript news.js paste this in make the necessary changes and we do need another link for this item as well so we need to go to the nav bar let's copy one of the links paste it we'll make the necessary changes and we will have a third page now as you've probably noticed each one of these components that are representing individual pages have all of the same markup they include the navbar they include the content that's not really great because that means if we want to keep this same look and feel we need to go into each one of these components and we need to modify whatever it is that we need to modify thankfully react router lets us define what is essentially a layout component or a layout route so that we can define the layout of our application and all of the other components essentially inherit that layout and we will look at that in the next lesson in the previous lesson i introduced you to react router which enables us to build single page applications so here we have a single page loaded into the browser and whenever we click on these links we're not navigating to another page these are react components that are dynamically loaded and react router makes all of this possible and the best thing is everything looks and feels the same except that the reason why is because they all have essentially the same markup they all reference the nav bar they all have the same div for the content container and that makes maintenance a nightmare because if we need to make any cosmetic change to one of these then we essentially need to replicate that change in all of the other components that's a nightmare we are human and we will mess something up so thankfully we can create what's called a layout route which allows us to essentially define a component that has our layout which in our case is the nav bar and then the div container for our content and then the content itself can be inside of the home react and javascript components so the first thing we are going to do is create a layout component we'll just call it layout.js there is no magic in this name and since any one of these components has our layout i'm just going to copy and then paste into layout and all we need to do is take out our content but the react router needs to know where to inject our content in our layout and we do that with a component called outlet so we need to import outlet this is from react router dom and all we have to do is use outlet that's it at least as far as the layout is concerned we do need to go to our index because that is where our routes are defined and we need to add that layout route we do so as a normal route so we're going to use the route component we don't need to specify a path we can and we will look at that here in a moment but for right now all we need is the element prop and we want to specify the layout element now we do need to import this but essentially this is going to serve as the parent route for our home react and javascript routes so it allows us to nest our routes so you can essentially think of it as these content routes for home react and javascript are inheriting the layout route i mean that i guess that's one way that you could look at it let's import the layout component so that's we don't run into any errors and then finally we need to go to the other components and we need to get rid of everything that we don't need so that is the nav bar that is the div element for our content and once we get that done and we view this in the browser we are going to see essentially the same thing but our application is going to be a lot easier to maintain so with these final edits we will save the file let's go to the browser and there we go we can navigate to these individual components just like we did before and everything looks good now i want to add some margin to the top of our content and all we have to do is make that change inside of our layout so we'll use the class from bootstrap that's going to push our content down just a little bit and one change is now reflected in all of those components now one of the really cool things about layouts is that we can use as many layouts as we want like for example we have our layout for home react in javascript but let's say that our application has an admin section so that we can manage the different topics that we want to view and of course an admin section is going to look very different from what the front end of our application is going to look like so we could define another layout for the admin section and only the admin section by just defining that layout route and then the children of that route would be for the admin section but even then you can nest a layout inside of the layout like for example with our application we have the home page and that's great but we also have these react in javascript news which i think are kind of a different section at least as far as the url is concerned like for example if we're going to view a news topic i would think that the url would be news slash and then whatever topic that we were wanting like react javascript or whatever else so home would still be the root of our application everything else would be news well that's easy enough to do all we have to do is just add another route that is a child of our layout but the path in this case we'll say is going to be news and then we will put the react and javascript routes inside of this news route we need to get rid of the slashes in front but this is essentially going to create routes so that news slash react and news slash javascript are going to work let's change our nav bar so that the links reflect that so that we will have news in front of react and javascript so that now we can navigate the url is now what we would expect we have news as the first segment and then our news topic but we could also define a layout let's create a new file we'll call this news layout let's copy the contents of our layout component because we need that outlet but we don't really need anything else but to prove that this is going to use the news layout we will just say news layout then we will have our content we need to import this inside of our index so that we can use it in our routes and we will use this as the element for our news route so now whenever we go to any of the news routes we will see the news layout because we added that as part of the news layout so for javascript and react we see that if we go to home that's not going to be there all we see is home page so we are using essentially two layouts together in order to be able to show different content based upon the url let's get rid of that news layout because well we don't need that so the next thing that we are going to talk about are route parameters because it's great that we have react news and we have javascript news but if we wanted to add any other news topics we would have to create a component for that topic so that we could of course navigate to that component and view the news but since our topic is actually part of the url we can make the news dynamic so that we would have just one component for fetching and displaying the news information and it would dynamically load the appropriate content based upon that segment in the url and you will learn about route parameters in the next lesson i've said it many times in this course but rewrite software to work with data and that data controls how our application looks like for example we have three links home react news and javascript news now i don't really care about home but the two links for displaying news results they essentially do the same thing the topic is of course going to be different but the type of data will be the same so in my mind it really doesn't make sense to have two components that do the same thing it would be nice to have just one component and then the results that we see will be based upon the topic in the url because we have the topic as the second segment in the url so i want to be able to grab that value so that then we know what type of news that we want to retrieve but then i also want to take it a step further because as it is right now if we want to add another topic we have to create another component we have to create another route and then we have to add a link to the navbar i want this to be completely soft coded so that we can have just an array of topics and based upon that array the application is going to automatically populate the nav bar and then whatever we use to display our news results will well it will display the news results based upon that topic so first things first we need to know how to get the values from our urls so this is going to be dynamic and whenever you have anything in the url that's going to be dynamic you want to use what's called a route parameter so for example our news route we could have a route parameter as the second segment you start a route parameter with a colon followed by a valid javascript identifier so this could be news topics or just news topic and then this is essentially going to be a value that we can pick out and we can use within our component but you're not limited to just url segments if you wanted to use a route parameter within the query string you could do that as well all you have to do is just define another route parameter so you can have as many route parameters as you want in your url as long as the router can match the url with a given route now for our purposes i don't want to use the route parameter here inside of the news route i'm going to change one of our existing routes inside so that it is simply going to be uh we'll call this news topic and instead of react news we will have another component called news results and that of course means that we need to create that file so let's create the file let's go ahead and import this here so that i don't forget to do that later because i will that always happens and to start all we need is just a copy of react news or javascript news so i'm just going to grab react news because that's what my eyes went to first we'll paste that inside of news results so inside of this component is where we will get the value of that url parameter but to do that we need a hook and so we are going to import a hook called use params this is from react router dom and it's just a function that is going to give us an object where the properties are the url parameter names in this route so this is going to give us an object let's call that object simply params we'll call use params and we will have a property called news topic so let's output that so that we can see it in the browser and so no matter what we do as far as the url if we go to new slash react we see react if we go to javascript we see javascript if we go to cars we see cars so that is working well what i want to do now is automatically build our nav bar the first thing i want to do is change a bad decision on my part the layout component that we created i want to rename that as app because that is essentially what this is this is our app component so i'm gonna change it uh layout was good for the example of layout but ultimately this is our app component and what i'm about to do inside of this is going to make sense as to why i want to change it because here i'm going to define the array of our topics so i'm just going to call it topics we want react we want javascript and i guess let's make this look like how we want to view it so it's going to be react but let's do this let's say react js because if we have a news topic of just react we're going to get a lot of stuff and then we will pass those topics onto the nav bar we'll just call this prop topics and so inside of navbar we then need to generate the li elements for our nav items as well as the links inside of them so let's destructure our props so that we have our topics and let's generate those elements we'll call this list items and we want to map over our topics so that we have the item we're also going to get the index because there's one thing that i've neglected to tell you about creating a collection of things i'm sure you have seen the error inside of the console but we're going to fix that here so we want to create an li element with a class name of nav item and then we want to create a link element where to is going to be a string to where we will say news slash and then we will have the item which is going to be the topic we want to set the class name to nav link and then we want the text of the topic which is our item variable and then once we have those list items we want to display those in the nav bar so let's do that so we will have our list items let's go back to the browser uh we have an error props is not defined that is inside of navbar.js uh where did we use props oh yeah so we need title and we need topics although we haven't used title in this case uh let's see where else and we're still using props somewhere so i don't see props where is oh yeah okay so now there we go our navbar is automatically generated with our topics we click on these we see the topic and let's pull up the console so that we can look at the error that i know is there it says each child in a list should have a unique key prop so essentially what we need to do is add a key prop to each one of these li elements that we create and the value needs to be unique for this particular collection which in our case is the index i typically call that i i but let's do this let's call it index so that that's clear as to what that is so by providing the index that error is going to go away we have the functionality that we want where our navbar is dynamically loaded based upon our topics and then we are using a single component for displaying the news for those topics so now in the next lesson all we need to do is add that functionality so that we make a request to the news api for our given topic so that we can display that in our component our little news application is ready for us to make a request and display the results in the browser but first of all we need a news source and we have one with newsapi.org now they do have paid subscriptions but they also have a freebie where you get 100 requests per day which is a much better quota than weather stack however we still need to be careful because if we do things wrong if we set up our component incorrectly and we are making requests we could reach that quota within just two seconds so the last thing that we are going to add code wise is going to be the http request that we make so just keep that in mind you will have to set up an account so that you can get an api key but that's it it's very straightforward to use all right so because we are going to be making a request and we want to do something with that response we need to store that response in state we also need to work with side effects because we are going to make an http request so we need to import use state and use effect let's go ahead and set up our state let's call the variable results and our function set results and we will initialize this as an empty object that way we always have something to work with even if there are no properties and next let's talk about our effect all right so let's first of all write a message to the console saying that the component is loaded because whenever you start dealing with components that are loaded through the router things can behave a little bit differently than what you would expect so let's go to the browser let's pull up the developer tools and we will see loaded already the reason being because we are on react.js and that makes perfect sense if we navigate to javascript we see loaded once again if we go to react.js of course we see loaded if we go to home we don't because that code isn't there but every time we go to either react or javascript we see loaded being added to the console okay that's kind of what we are after but let's throw in states because every time we make a request and that request is successful we are going to change our state so let's set the results to an object that has a property of x with a string value of y and this is why we are not making requests right now let's go to the browser and we can see we would have already reached that quota very quickly so we are in an infinite loop right now and um let's see if i can stop that quickly if we wait too long the browser will become unresponsive we'll have to close the tab and yeah looks like we've reached that point which is fine so let's just copy the url let's paste it in let's close the old tab and we'll talk about what happened there so remember that this is a function component so this function react news is going to execute every time that the component re-renders well it's going to re-render every time we change the state so the function executes the side effect function executes we change the state that forces react to re-render which means it executes react news it executes the effect it changes the state so we get into this infinite loop and we never get out of it so then what happens if we emulate the component did mount functionality so we're passing an empty array as the second argument to use effect let's pull up the developer tools this is going to get us a little closer but this is where things might behave a little bit differently than what you would expect so we are on react right now we of course see loaded in the console if we click on javascript a new loaded is not added to the log if we click on react once again nothing is being added to the log however if we go to home then we go to react we see loaded if we go to home and then javascript we see loaded was added again the reason is because remember that for our news results that is a single component and so as long as we click on a link that has a route to that component it is already loaded so there's no reason for that effect to execute again unless if that component is unloaded by going to home so that whenever we click on react or javascript that has to load the news results component again which is why we see it added to the console so this is close but there's still some room for improvement because we want to see loaded whenever we navigate between react.js and javascript well remember that this array is the dependencies for our effect so that if the dependencies change then the effect is going to execute again well our dependency is basically the url it's the second segment and we know what that is because that is our route parameter so let's do this let's destructure this params so that we have news topic and then we can use that as a dependency for our effect so that then the effect is going to execute now whenever our route parameter changes so we click on react it loaded we click on javascript it loaded go back to react go back to javascript we can see that it is now being added to the console we go to home it's not we go back to react it is so this is the functionality that we want for making our requests so now let's go ahead and let's make our request because before we can display this in the browser we do need data to work with so i'm going to use fetch and i'm going to paste in the majority of this url we're going to use newsapi.org version 2. they have this everything endpoint which well it gives us everything and the query is going to be our news topic we're going to sort by popularity and then the api key so from there we need to work with the response so we'll get the response convert that into a javascript object with the json method and then that is going to give us an object that we can use to generate our items and what we need to do here is basically just set our results to this object so that we can work with that outside of our effect and let's initialize the variable called output and we'll just have this be empty so that if for whatever reason we don't have any news items to display then we'll just display nothing at all so let's use a property on our results we want to make sure that everything is okay there is this status property and we will check to see if it is okay if it is then we will go ahead and generate our results so that we will change the value of output based upon our results this has a property called articles that we will map over and then we will work with the individual article as well as the index and i'm going to paste in the markup we're going to use the bootstrap cards once again because well it just makes things a little bit nicer to see inside of the browser and there's nothing really special we have the card body we have the title which is going to be the article title so we will use that this subtitle is going to be the author so there's this author property on the article and then we will display some of the content now this isn't the full content because the api doesn't give us the full content of the article it's going to give us a little blurb and then tell us how many characters are left but then finally we also need a link to take us to the article if there's actually something that we want to read so we want to use the url property on the article and so that is going to give us the output although we do need the key prop which we will set to index and then we will output our output let's put this inside of a div underneath the title for our news topic and we will output that there so whenever we go to the browser we see that there's an error results on line 19 so let's take a look and right there that should be results let's go back and there we have some results this is for react js and we can click on any one of these uh let's go to the one on neo and was this yes uh this was automatically set to open up a new tab so that's nice and there we have that article so let's close that let's go to the javascript news the results change this looks interesting why would javascript pull up something on cryptocurrency but uh there we have that article on slash dot and if we wanted to add another topic let's do that let's go to the uh that was inside of app wasn't it we had that array so let's add guitar and whenever we go back to the application we will see guitar in our nav bar let's click it then we will see the articles for guitar react unquestionably changed the way that we build web applications yeah angular started us down this path but react made it so much more approachable and it's my hope that as i leave you that you have the fundamental understanding of how to effectively use react to build applications of course i know you'll have questions we all did and still do so when you inevitably hit that first roadblock i recommend hitting the react documentation at react js.org react is well documented and it is the source of truth when it comes to how react works and naturally you can also head over to tuts plus where there are lots of articles tutorials and courses just waiting for you and we are all ready willing and able to help and answer your questions thank you so much for watching this course please feel free to contact me through twitter or the touchplus forums if you have any questions from all of us here at tutsplus thank you and i will see you next time you
Info
Channel: Envato Tuts+
Views: 57,476
Rating: undefined out of 5
Keywords: Tuts+, Envato Tuts+, learn react 18, react, reactjs, react tutorial, react 18, reactjs tutorial, react js tutorial, learn react js, learn react, react tutorial for beginners, web development, react 18 tutorial, react crash course, react 18 new features, programming, react course, react new features, react 18 changes, learn programming for beginners, react version 18
Id: l4G2MVgXFkw
Channel Id: undefined
Length: 220min 49sec (13249 seconds)
Published: Wed Jul 27 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.