React JS Full Course for Beginners | Complete All-in-One Tutorial | 9 Hours

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello and welcome to nine hours of react tutorials for beginners this video is made up of 23 tutorials for learning react that build upon each other much like the chapters of a book you will build projects and learn the fundamentals of react before beginning i recommend that you already know the basics of html css and most importantly javascript after all react is a javascript library throughout the tutorials i will mention links being available in the description below i have compiled all of these links into one github resource that you will find in the description hi i'm dave gray and i'm the creator of these react tutorials you can subscribe to my youtube channel for more tutorials like this one and you can follow me on twitter too let's get started learning react with chapter one congratulations on your decision to learn react it's a javascript library for building user interfaces and this can be one of the most profitable decisions you could make as a javascript developer at least in today's economy and if we look just a little bit closer at react some wikipedia information here it is maintained by facebook in a community of developers and companies it's very popular right now and it was initially released in may of 2013. also the website for react is react react.js.org and that's where i begin the tutorial at right here there's documentation here for react just like we would find on mdn for vanilla javascript now i mentioned a profitable decision if we look at the jobs listed for react in the kansas city area which is the area that i live in as of today there's 208 plus react jobs listed now there may be a few that slipped in there that just have the word react in the listing however if we look at the salaries we can tell most of these jobs are truly for working with react js and at the high end we can tell there's 92 or more that offer a hundred and thirty thousand plus for the position and you can see the other listings as well to get started with react today we're going to need to make sure you have nodejs installed and if you go to nodejs.org it will identify what platform you're on i'm on windows and it knows that already and then it will offer the appropriate download likewise you can install node.js on mac and linux after you do that we will come back at the command line and i will show you how to check the version but you may also want to go to store.chrome.web and there you can search for react dev tools and i recommend installing the react developers tools extension i believe it's available in some variation for firefox and for safari however i know it's available for chrome so you may want to install this extension as well now today i'm going to be using visual studio code and this is visual studio code opened up to an empty folder which is what you'll want to do maybe start a react projects folder i've got mine under react series and when we install or create an app with react it will create the project folder for us so we just want to have a parent folder where we can have all of our projects now in visual studio code i can press control and the tilde to open up a terminal window and this is my terminal window so now let's check what version of node you have if you've installed node we can type node dash v and just verify that it's installed and you can see i have version 14.15.4 from here we'll create our first react project so let's type npx and then we'll type create dash react dash app and then we'll type the name of our project you can name it whatever you want to i'm just going to name this zero one tut as in the first tutorial in this series and i'll go ahead and press enter this process is going to take a few minutes and so i will come back when it is complete when create react app completes you should see a screen like this at least if you have your terminal open in vs code and set it to full screen like i did you can make it smaller or if it starts out small at the bottom you can click this arrow and bring it back up and there i'm scrolling back to show what it shows in the terminal but now it is complete and our full project is in the zero one tut folder or whatever you named your folder a couple of quick things before we go to this folder that you may want to do one is to go to the extensions tab in visual studio code and here search for es7 react and if you click on that you'll see an extension that i already have installed and enabled and it's es7 react redux graphql react native snippets this gives some useful snippets and so you may want to enable this in your vs code as well just a recommended extension i will use it during this tutorial series after that i can come back to the file tree here which just shows the folder but if i go to the file menu and choose preferences and then go to settings and now when i can search settings i'm going to type emmet that's e-m-m-e-t and this will bring up the settings for emmett and find emmet include languages and it recommends right here or at least gives an example of javascript and then a value of javascript react so if we want to use image shortcuts and sometimes i do although i don't always do that especially during tutorials i like to type things out but if you want to use image shortcuts we'll add the item here and we'll just type the key javascript and the value should be javascript react and we'll click ok and now that is set and we can use emmet as we write react okay with those complete i believe we're ready to go into our project folder now and we can do this in the terminal as well and so if you have the command line available in your terminal you can go ahead and just type cd and then type the name of the folder you have and that is zero one tut for me and now that i'm in that folder i really want to just open up visual studio code in that folder and i can type the word code in a period and i'll open up a new instance of visual studio code when i press enter and now we can close the previous instance and i will expand this and we've got visual studio code opened up in the zero one tut folder create react app has created all of the contents you see for us including the folders and the individual files let's start at the top the first one is the get folder so it's already initiated git and if you're used to using git with your project and probably store your source files on github it's already initialized and therefore it already has a git ignore file and if you've worked with node before you know you need node modules it contains all of the dependencies but you don't want to store all of those files in your repository so node modules is included in the git ignore file and if i click that we can see it right here under dependencies and that's why node modules is a little bit of a different color here in my file tree it's grayed out and that doesn't mean it won't work with our project it will it's just not included in the git repository besides that we have a public folder and we won't do much with the public folder and that includes the index.html file and the way react works is there's only the one html file that loads into the browser and after that react takes over and presents the rest of the content so you'll only have this one file and if you need to include some more meta tags or some other resources and you want to do that in html this is the place that you would do that other than that we won't really do anything in the public folder we will work in the source folder so let's expand this and you can see several files are already included in here and that includes a few files that we don't need we won't use the app.test.js we also won't use the report web vitals dot js or the setup test dot js they just will not be part of something we do with this tutorial so we can delete those you can do a right click and choose delete to get rid of those or you could just press the delete key with those files deleted we'll go ahead and leave the source folder open for now but let's look at the package.json which you should also be familiar with if you've worked with node before but if not this will be a quick rundown it's got the project name the version it lists the dependencies here and this is important because this is how node knows which dependencies to pull in from the node's module folder other than that it also has scripts and these are important because we will be running them and we'll even use this npm start script to show the initial project that create react app builds for us to start our project with or to modify when we want to build our project when we finish writing the source code we'll use the build script as well other than that there's nothing else really in the package json file that we will use right now and then there's a readme that explains some of these scripts and what they do so our main focus will be here in the source folder and let's look at the index.js file now it's got a few things in here we can delete because we removed the report web vitals and you see here on line 17 it says report web vitals so let's go ahead and highlight all of that and just i'll hit backspace and get rid of it also that means we don't need the report web vitals import up here either so i can highlight that and also delete that now i'll save the file and since create react app initialized a git folder for us and we've already got git initialized you can see in the file tree that my index.js changes color and the m stands for modified and if you're used to working with git you're probably familiar with that that means i've made a change to my file now in the index.js you can see if you know javascript you've got document.getelementbyid and we're selecting the root id in the html file and that is where react injects our app and that is the built-in component that comes with the setup project here the from create react app so it gives us the first component and this is the parent component for all the others and it is injected into the html and therefore all of the other javascript components will be injected as well when we build the project and so we can look at that app.js file and we can see the little bit of source code in here it looks a lot like html but this is jsx and this is something we will cover more in detail in the future but that's what is being returned by our app function and that is jsx we see right here in the return very similar to html not quite the same thing with that said let's take a look at our project by running the script the npm run and we can do that by opening a terminal once again you can go to the terminal menu and choose new terminal or you can do what i do and press control and the tilde at least i'm on windows and that opens up a terminal window as well from here i'm going to type npm start and this will launch a local development browser should be at localhost port 3000 and we'll be able to view the initial project setup and here we have the intro project it has the react logo going in the rotation and it just tells us edit source app.js and save to reload because this is a development server so it will display our changes pretty much automatically i'll pull this over to the right and then we'll resize vs code to the left and i'll go ahead and close the terminal and now we can make a change here in our app.js i'll hide the file tree as well it says edit source app.js code and save to reload and say and save to see changes and i'll go ahead and save the file and now you can see in our file it says and save to see changes so this will be very handy when we're working with reapp because we will see the changes from react automatically i'm going to go ahead and show you how to stop the project as well so back in the terminal if you press ctrl c that will stop the local development server the app is still loaded in the browser but now we won't see changes okay in the next tutorial we will start modifying this generalized app that we start out with and learn how to apply more changes to our own components in react in this tutorial we're exploring the app component which is the default component created by a new react project and then we're also going to explore jsx what it is and what you can do within it let's start by looking at the index js file that's created when we use create react app and we import our app from the app file because each component gets its own file and here you can see that the app component is injected into the dom and it's being injected into the element that has the id of root and that is the default when you create a react project so let's look at this app component and we'll look at app.js i'm going to go ahead and hide the file tree so we can see this a little bit better and also point out that i have the default project running over here by using the npm start command at the command line and so it's on the right and as we make changes to this file this will update the local dev server for react using npm start will make automatic updates as we change this file so we could change some of the code here where it says save to see changes i can just get rid of this and say save to see what i change and save the file and we should see the change over here on the right in the project okay now looking at our app component you can see it is also allowed to import resources and we're importing an image to use as a logo we're also importing a css file that goes with the app component in its app css and then you'll notice the component is a function modern react uses functional components there was a time that class components were used more often and that is not the case now i do not plan to go back and cover class components in this tutorial series but you may see some legacy code with class components there is also an export statement at the bottom that just has a default export for the component that you create we can use this default component created by create react app and just look at the app component to learn more about components before we create more so let's take a quick look and you can see it starts out with the function keyword this could be an arrow function it shouldn't change anything and when i create other components i will probably use arrow functions now the return statement and the component returns jsx and we'll talk about that more in a minute which it's all javascript but inside any function component we create we can add more javascript so i could define a variable up here called name and i can put my name in it and that's fine and we can refer to this variable later inside the jsx the jsx is javascript and it stands for javascript in xml it resembles html very much but it's not quite the same you can see we can write html here's a div here's a header element here's an image element but notice some of the attributes are different we don't have a class attribute that's reserved so we have to use class name also there are some others that you may encounter like instead of 4 and html4 but class name is a very common one other than that some of the other attributes you see like the source attribute here the href attribute the target attribute the rel attribute those are just like they would be in html and then jsx allows us to put javascript expressions in the code and that's really what makes it so powerful so here you can see instead of a normal source value we're referring to the logo variable that's pulled in from the lexical scope here of this component and we have defined logo up here as it's imported and it's pulled right into this image tag as the value for source and then the image is displayed in the component all in all you could say jsx provides a template for the component layout and also it is important to know that jsx renders data as text when it displays it so if we provide a text string or an integer for example either type of data it would be rendered as text so let's look at an example of that here we have our header let me put a paragraph below the header and inside the paragraph we could just put a word like we would see in html and here i'll just put html and we'll save that and that will display well it looks like it displayed way below here let me go ahead and put it inside the header i didn't change the default css let me put it right under the link to learn react and now we should see it above here it says html but that is simply html that we've put in there but if we want an expression with a value we could do something like that and i could put dave as a string and now we can see we get dave rendered to the page as a string we could also change that and put in a numeric value an integer say the number one and that will render as a string as well we can also do that with arrays so let's put in an array that counts well it has three elements one two three and you can see the array is also rendered as a string on the page one two three now if we removed the curly braces which says hey that's a javascript expression now this is just back to html and it's going to render exactly what is in there and now you can see we get the brackets and everything but once again curly braces says this is a javascript expression we cannot however display an object and we will get an error when i do this but let me go ahead and show you i have a and then just b notice i've got double curly braces to say it's an object but an error should pop up over here i may need to refresh the page to see the error yes there it is objects are not valid as a react child so no objects that cannot be rendered to the page so just remember we can't do that with objects like we can with arrays also a boolean will not render to the page so let me go ahead and save this first so we get rid of the error now we're back to our normal page and of course we rendered nothing there but if i put in a statement like true strict equals false normally that would return false right or i could say one or two strict equals four that would be false but notice we're not getting faults to the page because it will not render a boolean i'm going to put the variable name in here that we created above and let's go ahead and save this and yes there's the value of the variable so that javascript expression works just fine now i'm going to select all of this and in visual studio code i'm using windows if i press shift alt and a i can comment something out notice how a comment is created first the curly braces are used to say hey this is a javascript expression and then you it uses comments as we would within javascript to comment this out and if i save it won't show up so that is an extra step kind of in commenting out some code here in the jsx but that is how visual studio code does that and then we can just delete this i believe if i select it around it's not going to do it right let me go ahead and try that and i'm going to press shift alt and the letter a again oh it did it it got rid of it so hey that's great and dave is back all right let's go ahead and remove this and let's just change some of the template code here we'll leave the logo but let's create a basic hello world like you might expect in a first project and we'll we'll change a couple of things around we'll experiment with it just a little bit so let's say first hello world with an exclamation mark and we can see the change over here no problem now let's change this to say instead of hello world like this let's put in the name get rid of that extra curly brace and it says hello dave so we can put in expressions like that let's take this a step further and say we wanted to load a random name so instead of defining a variable here let's define a function and let's call this function handle name change and you'll often find that functions are started with handle as a convention or something similar to that however in the future we would be handling a click event or some other type of event but here i'll just name this handle name change so we get used to starting functions with the word handle as a convention and i'll define names inside and instead of just dave i'm going to have bob and i'll have a single quotes kevin and then i'll go ahead and include dave in there and after we define our names array let's define a random integer and we'll just call it int and we'll set it equal to math floor and we just want this to be from zero to two so we're going to use math marth there we go math dot random and we'll take it times 3. if we want it to be between 1 and 3 of course this is in my basic javascript course but we would have to add one to this as well so right now we have between 0 and 2 and a random number and then we're going to go ahead and return names and the element from names that matches up with our random number so we're going to get a random name back now instead of putting name in here we can put in handle name change and we can just go ahead and call the function right there so when this loads it will call the function handle name change into action so let's save this change and we get hello kevin now if we reload we got hello dave let's try it again hello kevin maybe we'll get bob sometime still going between dave and kevin right now there's bob so it took just a little bit one out of 3 chances there 33 33.33 i guess if we're being specific but the point being is you can call a function in here as it's also a javascript expression that we're inserting into the jsx today we will be adding functional components to our project now a quick recap we are running the example react project over here to the right and we used create react app to create our project to begin with and then we looked at the app function this is a functional component and to understand it better we looked at the jsx within the app and we change some of that default jsx and right now we're calling a function here called handle name change and it loads whatever name is randomly generated with this function up above but today we want to add more components to react because that is some of the power of react we can create functional components and they're reusable i'm going to use snippets and this is es7 react redux and graphql snippets i believe is what it says over here if i were to extend that but just go ahead and add this extension to vs code if you don't have it or if you don't add the extension you can type out everything you see me quickly generate with the snippets now before i go ahead and create another functional component let's look at the index.js notice in this index.js we have an import statement where we import the app component as it's injected into the dom and now we're going to do the same thing we'll create a component and then import it but we'll import it into the app component which is the parent of all the other components in the component tree so notice we have our div with the class name of app and then we created a header so instead of this header let's just go ahead and create a new file and i'll do that over here in the file tree and i'm going to name this file header with capital h dot js and now that i have this empty file i'm going to use the snippets now in windows it is control alt and the letter r i believe on mac and linux it might be command shift p if if it is not command shift p go ahead and press that and then search for es7 snippets and you'll see what the control is for that let me go ahead and show you that i can do that as well here where i can press ctrl shift p in windows and then if i type es7 snippet search there it shows me control alt r for windows is the command but i could also just choose it here so now i'll press ctrl alt r here in windows and i'm going to type underscore r a f f c e and this will help me create a functional component it will generate a generic one so i'll press enter and here's my functional component and notice it inserted the name header already because i've created header.js and now we're not bound to use div it's very easy to get caught up just using divs when you're using react but it's best to stick with the semantic html we do not have to give up our other practices just because we're using react so i'm going to create a header element here instead of the div element that we have and now inside the header i'm going to place an h1 and now we can put whatever we want here i'm going to call this groceries list because if i make a list it's usually to buy groceries so i'll go ahead and save that as our header and there we have our header component it's already exported here and that's what we need to happen to import it into the app component so now we can import header from and then we have dot slash because it's in the same folder header we don't need to add the js so now we've imported header we haven't used it yet and we're also going to get rid of the logo so let's go ahead and get rid of this import and now we'll go ahead and change some not all yet but some of the code we have inside of our jsx here so i'll go ahead and take this header out and i'm going to put the header in and you can see it's a custom element essentially here in the jsx that says header we've imported it and now this has full color so you know we're using it and we can save this and of course things will change and we have our groceries list header now at the top so we created a separate functional component and imported that component now let's create another one and i'll create a new file over here and i'm going to just call this content.js and we'll do the same thing i'm going to press ctrl alt and the letter r because i'm on windows and then it's underscore r a f c e and we've got our content functional component started once again i'm not going to use a div i'm going to use a main element as this is the main content of the page in here i'm going to paste what we had and maybe alter it just a little because i went ahead and copied the header element that we didn't need everything else looks good for now oh we won't use the image and we're not importing the image remember we would have to import that into the file if we did and then i can just clean up the blank lines and i'll go ahead and tab over to keep this structure the way we're used to seeing it but we don't have handle name change here either so let's go back to our app component and let's take this logic out of the app component and we can put it directly into the content component so now we still have our function available for our jsx and we can save this but we haven't imported it yet so we don't see it over here let's import that right here import content from dot slash content and now we can add our content functional component right underneath the header and save and we got hello bob because our function is still working so if we reload we might get another name yes we got hello kevin and maybe we'll get dave on the next one help kevin again it's all just random if you remember and now we still need a footer so one more component to create and we'll call this footer with a capital f footer js now that we're here ctrl alt r and then underscore r a f c e and we've got our generic footer component and if you remember from semantic html there is a footer element so there's no reason to just stick with the div and now we can add just a little more logic to our footer above the return in our footer component let's go ahead and define a variable called today and let's set that equal to a new date object and from there we'll be able to refer to that inside our jsx so let's go ahead and create a paragraph and here we're going to say copyright and then we'll put the copyright symbol which is and copy or ampersand copy with a semicolon and from there we can refer to the date with an expression and all we really want is the year so we can say today dot get full year and we'll call that and then we of course need the ending curly brace and if we save that of course we don't see it here yet because we need to import it we will come back to the app.js import our footer from [Music] dot slash footer and then we need to put it inside the jsx of the app component and save and there we get copyright 2021. so with the three functional components that we've created today you can see two of them encapsulate logic and of course they all could but we have the handle name change encapsulated inside the content component and we also have just a little bit of logic encapsulated inside the footer component the parent component for all three functional components we created today is the app component and we had to import all of the components that we created header content and footer into the app component and then we were able to place them inside the layout of the jsx of the app component now you may have installed the react dev tools i've previously recommended if not remember you can go to the chrome web store and search for react dev tools and there you'll find the react developer tools i highly recommend installing those let's briefly look at our project with the react dev tools now i'm going to right click and choose inspect to open up the dev tools and react dev tools just become part of your regular dev tools in chrome i'll drag that down and if i choose console and notice instead of to the right today i'm showing the console at the bottom of the page and you can click the three dots over by the x on the right of the dev tools and kind of choose where you want the dock to be so i usually have it to the right if you've watched some of my other tutorials today i have it to the bottom and that's fine now here's our app running and if you click the arrows notice we've got a couple of extra choices here and we're going to use components these are part of the react dev tools and if i use components i'm just going to drag this up you can see the component tree so here's the parent app and then here are the three components that we created today and as we add more components to this project and as you learn we'll continue to observe these and see how the component tree grows today we're learning how to apply styles to react components and to apply css styles there are several ways of accomplishing this goal really and the first is to create style sheets so we see in the file tree as you might have already seen we have an index.css we have an app.css and it's very common to create one file or stylesheet if you will for each component file however in a small project like this it's not unusual to just use one file so the files are not really for scoping it's just for organizations so you know your app.css goes with the app.js file but in a small project you could just really put it all in the index.css and that's what we will do but i also want to talk about several other popular ways to add styles one is with a very popular package called styled components and you can see that here it's at styledashcomponents.com and you could explore this if you want to this would be outside of the scope of just learning react so i'm not going to go over it in this series however i may do a tutorial in the future you can see there's npm install dash dash save style dash components and it tells you how to use it here and give some guidelines right there on the website the other way that you might add styles and let's look at the header js file in our project is to inline the styles inside the jsx and that is not unusual either and sometimes even though you're using style sheets it's useful to do so so it's important to learn how to do that so let's start here in the jsx and i've got the header element and i will type style and then equals and put our curly braces now to inline this it's really kind of a style object so we need another set of curly braces and from there we can specify the keys and the properties so i'm going to go ahead and hit return and start on a separate line here and change the background and now notice there's no hyphen i'm just changing background color like i would refer to it in javascript because jsx is javascript in xml so this is background camel case color and then in quotes we want to put what we're going to use here so i'll put medium blue and now a comma just like i'm creating an object and color once again in quotes i'll put the hex abbreviation value for white now if we save this we should see the change oh and i've got an error because out of habit i put a semicolon this is more like an object it should not have a semicolon and as the last in the list it doesn't even need a comma so i will save now and now we see the background color change for the header and the font color change for the header and we just in line this style now instead of this approach we could assign this to a variable so if i just start up here above the return i can say const and just put my header style and set this equal to and i'll just cut this out of here including the inner curly braces and set it right here now i'll go ahead and put the semicolon although notice when we create our components that our snippet extension doesn't add semicolons like there's not one here after header although there could be i'm still in the habit old school from javascript of adding the semicolons not everyone does but now i've created this header style variable and i can just insert it in the expression in the jsx and if i save we should still have our colors there with no error and that's fine and just to show that that's working let's change the color of the blue and now we have a royal blue header background okay let's remove these changes for now because i will not be using the inline style here in the header at least anytime soon save that back the way it was just a plain looking project here let's do a little bit of cleanup also in the app.js let's remove the app dot css import save that we can delete the app.css file and we can delete the logo we're not using anymore the svg and now i'm going to quickly insert some styles into the index.css that we'll see apply to the project okay i don't think you wanted to see me type all of the css or apply those changes as this is about react and not about learning css however i am going to go ahead and post a repo to github and link to that in the description so you could get all of these changes if you don't want to type them out and you can see i just modified the index dot css i put in a reset i put in a font size in the html element that will of course disseminate to the rest of the page i put in a min height in the body element that wasn't previously there and i might have changed the font family just a little bit or got rid of the first couple of choices i believe if i remember right i went ahead and left the app class because if you remember in the app.js we have a class name app that wraps everything else that we've put in here so i left that and have some styles applied there and then this isn't the driest of course dry meaning don't repeat yourself it's not the driest css as i left it so you could go ahead if you want to and peel each one of these out and create separate css files for each component and that would also work and so you'll see there's some drastic changes to the right and while it's still our basic app with a header main area for the page and a footer now it looks much more like you would expect it to and this is something we can build on as we continue to learn react and remember none of these styles will be applied unless the css is imported and here in the index.js file we do have an import of the index.css and that is currently where all of the styles are if you create a separate style sheet for each functional component you will need to import each style sheet into each individual component just as we used to have an import of app.css at the top of the functional app component so just remember every stylesheet needs an import statement to the functional component that it applies to in today's tutorial we're going to look at how react responds to events so let's look at the content component now react is a javascript library so just like vanilla javascript it can respond to many different event types we're going to specifically look at click event types today because they're so common currently in our content component we have a handle name change function and it is called into action immediately the function is invoked when the page loads we have the operators right here and so it's just called wants it doesn't respond to a button or anything else but today we're going to go ahead and create a separate function and we're going to call it handle click this will be an arrow function and inside this function we'll just log to the console and i'm going to say you clicked it and that's just as simple as it gets for now and inside the jsx underneath our paragraph let's go ahead and add a button element and we'll put click it for the text now when we call this function we just need a reference to the function and we have to use on click and then we're ready for a javascript expression in our jsx and we'll just use a reference so handle click and as i see some of the text scrolling off the screen i'm going to go ahead and press ctrl b to hide the file tree for now so we can see all of this code just a little bit better and we'll stay inside the content component so we've got a button ready to go and it will call the handle click function and from there we'll have to look at the console to see the you clicked it output so i'm going to save this file and we should really see the button show up over here and that's fine but we still need the console so i'm going to right click and choose inspect to show the dev tools and i've got the dev tool showing up underneath i'll click console going to clear out the default message so we have plenty of room here and we're ready to click our button so when i click this we see you clicked it show up in the console as we expect so that is how we call a simple function from a button click but what if we wanted to pass in a parameter to a function like handle click so let's go ahead and i'm going to highlight the handle click function and now in visual studio code i'm on windows but if i press shift alt and the down arrow it will make a copy of that whole function directly underneath i'm just going to call this handle click 2 oops i typed 3 there handle click 2 and we're going to pass in a parameter called name and now we'll go ahead and log the name so i need a template literal here to combine that so i'll say name and then i'll just put was clicked so there is our handle click to function and now if i click on the line in the jsx that has the button element and i press shift alt and the down arrow once again i'll copy that button down so we've made a second button element and this will call handleclick2 but right now it's not passing in the parameter so how do we do that well we need an anonymous function here and so we can start with the operators and the arrow like we'd see in an anonymous function and now handleclick2 can be called and we can pass in a name so i'll pass in my name now you may be used to seeing anonymous functions with curly braces and this would work but since they're on the same line oh we need a second curly brace here because it still has to be inside of an expression so this would work but because this function expression is on one line these curly braces the inner ones are not really required so i usually leave those out now our expression in jsx still needs to be inside of curly braces so that's how we would put in the anonymous function let's go ahead and save this and we should see a second button yes there it is below now when i click this it should say dave was clicked in the console and that's what we've got dave was clicked it looks like this long line here in the console is making the word dave wrap but other than that we did get the output we expected now it's worth noting at this point that we are using a reference to handle click on this first button and not putting the operators after it like we did with the handle name change if we put the operators after it it would be called immediately so with that knowledge you may ask well why isn't handle click 2 called immediately because it has the operators after it and that's because it's inside a function and it's inside this anonymous function that begins here and so this anonymous function is not called into action until the click and then when this function is called into action it calls this function we also get access to the event object when we click an event so let's have one more example i'll copy handle click to once again pressing shift alt and the down arrow and now i'm going to name this handle click three and i'm going to pass in the event just as e and now i won't use a template literal let's just log the event itself or the event object here and i'll need another button here so once again pressing shift alt and the down arrow and we have copied down our button with the anonymous function turn handle click 2 into handle click 3 here we need to put e for the event in the first operators here as the anonymous function is called and then we'll also pass it in to our handle click three let's save that and now we'll click the third button and notice in the console we get the full event object logged here and it has several keys and properties such as react name is on click we're more interested in the target right here and the target is the button so let's go ahead and leave the function call as it is with the event here and the event here but when we log now let's reference the target and see what we get in the console i'll save and let me go ahead and clear the console for some more room i'll click on the third button and now we just get the event target which is the button element itself with the text click it and we can even go further than that let's just get the inner text of the button i'll save this and now when we click the third button we just get the text click it as i mentioned react can listen for other events as well one of those events is a double click so let's come up to our paragraph element in our jsx and add on double click and here we'll go ahead and call our initial handle click function once again and let's save this and now when i double click hello let me clear the console again so sure of what we're getting i double click hello we get you clicked it and if i double click again you can see it has now been logged twice again three times so there are many different events you can explore to put into your applications and we'll be adding more as we continue to build out this application now i'm sure you're questioning what can i do to click a button and change the name of the greeting right now we just have this handle name change function and it's only called once and it's called when the page loads initially because the operators are right here so this is very vanilla javascript like we have a function defined up here at the top called handle name change and when the page loads we just call it into action like we would with vanilla javascript that's not thinking in a reactful way we want this to respond to something we do in react where the full page doesn't have to load but react will re-render the component that it's in and display a random name here and we'll learn how to do that with state as we learn about use state in the next tutorial today we're going to talk about a react hook called use state so let's look at the content component in the previous tutorial in this series we learned about how to handle click events so we see several handle click functions here and above we have a handle name change function that we've been calling since early on in the series and this handle name change randomly generates a name either bob kevin or dave and it gives a greeting in the page but this is done in a very vanilla javascript way we just define the function here handle name change and then when the page loads it's called into action down here in the jsx and we call handle name change with the operators right here and this is thinking in the old school vanilla javascript way this is not thinking in a reactful way at all we need to handle the state of our component and react actually gets its name because it reacts to changes in the state of the component and when there are changes then it re-renders the jsx that we find here in the return statement i'm going to press ctrl b to hide the file tree because we'll stay inside the content component for this tutorial and back at the very top of this component now we need to import our react hook and that react hook is called use state so we'll start with import and then curly braces and use state and we use camelcase there with state having a capital s and from there we'll say from react and now we can use the use state hook inside of our component so we will start out by defining what we will use for state and we're going to use a name and then we're going to use set name so this is array destructuring that we get from use state and the first value name will provide the current state at any given point in time and then set name is much like you would think it we can set the state with it so if you really want to think about it this way you could call name the getter and set name the setter if you're familiar with vanilla javascript objects so we'll set this equal to use state and we put in parentheses and now we can put data in here as default data for when the component loads and this would be the original state or default state and i'm just going to put in my name dave to provide a name to begin with for the default state and now that we have name i can replace our handle name change down here in the jsx with the value of the current state for hello name and when i save this we should see the change and yes it now says hello dave over here on the right in our application but this will always say hello dave right now it is just getting the current state the default state and we're never setting it so we need to change our handle name change function and what we can do is instead of returning the name or the random name value we can use the set name method here from the use state and we will pass in the value so now handle name change will set a name as the current state so let's go ahead and call the handle name change function now for one of the button clicks so instead of handle click let's put in a handle name change and we'll just use a reference here and let's go ahead and change the text of the button to change name and we'll save and now when we click the change name button we should call the handle name change function and that should change the state now we might generate the same name so after i click once it may be dave or it may be bob or it may be kevin that's just how our function works it could randomly be any one of the three so i'll click it several times we got bob we got kevin and back to dave now it could easily do the same name two or three times in a row as it just did with bob and now we're back to dave back to bob back to kevin so the button works it changes the state and by setting that state change react re-renders very quickly our content component and we see the name change notice we used const here because we never want to try to reassign the name value here directly we never want to try to directly modify the state of the component we always want to use set name when we change that and there are some gotchas it's kind of learning how to think about state in the correct way so let's look at some of these gotchas and i'm going to define another one let's say count and set count to spell count correctly there the second time and we'll once again use state and i'll set the initial state or the default state if you will to zero now in handle click let's go ahead and log the value of the count so we'll just put count there and we'll save this much and let's look in our jsx to see where we could call handle click and we don't really have it being called right now so i'll go ahead and replace handleclick2 and this anonymous function with handle click for our second button and we'll save now i need to right click on the application and choose inspect to show the console window in dev tools and we're on elements right now there is console let's clear out everything so we can see what shows in the console here and i've got my dev tools docked to the bottom instead of to the right you can change that with the three dots here and dock wherever you want to so up here if we click the second button it should call handle click and when we call handle click what should happen is the count variable i should say the count state will be logged to the console the value of the current state so let's click this second button and we get zero and that's what we expect as it is the default state now there can be some gotches and you have to start thinking about state in the proper way to avoid this so let's go ahead and add set count here to change the state and let's set the state equal to count plus one now what value would you expect to see when we log count here which is the state let's go ahead and save and we'll clear that out and i will click the second button we still get zero even though we set the count to count plus one which is zero plus one so the count should be one but the value of count is what was initially brought to the function and since it was zero when it began it's still zero here on the line underneath where we set the count to essentially one and if we even copy a second line and you'd think okay now we've set it to one and then we're setting it to count plus one again and it should be two that is really just not how this works so i'll clear that and click the second button and now it's one because we previously set it to 1 but it is not 2 and i should have shown you that it was 1 before because it did change it to 1 it just didn't show it so now it was 1 when it was brought into the function but if we look at the value of count again it's going to be 2 not 3 this will not add 2 to it because this value and this value are the same so this was 1 plus 1 and then we simply set count to one plus one again so it's still just going to be two and to display that let's go ahead and change handle click to and we will change handle click two to just simply log the current state again of count and now we can put handleclick2 here where we were calling handleclick3 we just need the reference and that should also allow us to get rid of handle click three altogether up here and we'll save and now if i click this button the third button the current state is two even though we had two of these here we had clicked it once before when there was only one so now if i click it again it's not going to turn into four it logs the state that was passed into the function which is two it doesn't change the value of count within this function even after we set the count and now when i click the third button it's three not four it doesn't add two to the count it only adds one because this was two plus one and this was also two plus one so we didn't really change anything there and it's three now that can be a little hard to wrap your head around so just remember that the value of the state the current value of the state comes into the function and we do not alter that and even though you might use the set count or whatever you use to set the state for your used state when you log to the console or use the value of the current state after that it will not have changed because that's what was brought into the function okay so i understand if that's a little confusing but what i really hope you can take away from this besides avoiding that gotcha is that you need to use const because you don't ever want to allow the state to be changed directly such as name or count we can name these whatever we want to and the convention is to name them what you're holding essentially describe the data and then in the function or the method you could say that follows it it usually starts with a lowercase word set and then camelcase and has the same name that the first value has here so name and set name and then we can use state and you can use state for more than one thing inside of a component you just have to define these and i hope you understand how we started out with the default state of dave and then we were able to call handle name change and set a new name as the state and that is why clicking our change name button continues to generate different names although it might generate the same name several times in a row because it's just random between those three names and now that you have a better understanding of state and the use state hook in react we're going to go ahead and be able to build out more of our project in the next tutorial as we output lists to our content today's tutorial focuses on react lists and keys you can see on the left i have visual studio code open and we are looking at the app.js file which contains the app component on the right we're running the react app in chrome and i have the dev tools open and the console is available in the bottom right now as we look at the app.js file we've added a header component a content component and a footer component let's go ahead and go over to the file tree to click on content.js that will show the content component we recently learned about click events and about the use state hook in react we're going to remove this code as it was just added to introduce concepts so we can highlight the handle name change handle click and handle click to functions and just press backspace to remove all of those likewise in the jsx of the content component we can highlight everything between the main element opening and closing tags and remove that as well we'll go ahead and get rid of this extra space to even out the main element opening and closing and leave a space in between and now let's look at our use state hooks where we set up the default state for count and name we're not going to use these states but we will use one so let's just go ahead and remove the first or i guess it's the second count and set count is we only need one state and instead of name and set name we're going to call this items and set items and now let's look at our default state currently it's a string that says dave but we want to change this the default state can also be an array and that's what we're going to do is put in an array of items and i will just paste this in and now let's look at our items i'm going to press ctrl b to hide the file tree so we can see all of the file better without wrapping lines and now looking at our default state that the app will open with we have an array that contains three objects and each object is an item each item has an id property a checked property and an item property the id is going to be the item id and it's numeric the checked property has a value that's boolean either true or false and then the item property is going to be a string that will describe our groceries that we're shopping for but you can see since these are just default i put in one example of a grocery item and then i just put in item two and item three i'm going to go ahead and save our changes to content.js and we should see those reflected on the right in the app and we do at this point the content component looks blank and we'll go ahead and drag up the console to give a little bit more room it's giving us a warning that items and set items is not used at this point we can just clear that out but let's look at the different options here with the two arrows and we can check our react dev tools and look at the components and let's go ahead and highlight the content component when we open this and now if we scroll we're not to props yet but look at state we have our array that has three objects and we can actually expand that and we can see each object that's inside of the array and this is in react dev tools and state and i'm looking at components here instead of console now that we've confirmed our default item state our challenge is to display the list items inside of our jsx we're going to do that with an unordered list so we can simply begin with an html element that would be an unordered list opening and closing tags but now in the jsx we need an expression and the way to display a list in jsx is to work through the list using map so we can say items dot map which is a higher order function and if you're not familiar with map not only do i recommend referencing that on mdn but i also recommend the tutorial that i will link to above on higher order functions that i created now with map we're going to go through each item and from there we'll have an arrow and then we need another parentheses as we iterate through the items each item will be a list item so let's start out with an li just as we would in html and we can go ahead and give this li a class name and we'll set that class name equal to item from there inside the list item or the li element we'll have an input element and now on a separate line i'm going to put the attributes for the input element and the first will be type equals checkbox the next is going to be checked and we'll set that equal to an expression and this will be item dot checked either true or false at that point our boolean value from above in our list of items and now i'll come back to the indent where the input started and i'll close it out with the slash and the greater than symbol so that's the input now we'll have a label for the input and inside the label we're going to label it with item dot item as an expression to display for the label and finally we're going to have a button and i'll just put in the text delete right now as this would actually remove the item we don't expect to remove the item when we check it we're just going to eventually draw a line through the item so we can still show the checked items and then separately remove them from the list when we want to we're almost finished with our list item but we've left out one key ingredient an emphasis on the word key i'm going to scroll this up just a little so we can focus here in the center of the page but each list item in react needs a key so we're going to set an attribute called key equal to an expression and in this expression we'll say item dot id so we can just use the id number of the item as the key now react needs keys for each list item and this helps react identify which items have changed which items have been added or which items have been removed because react reacts or responds to changes in state and it re-renders the jsx so react does need to keep track of those things and that is why a list item needs to have a key attribute in react now with those changes made let's go ahead and save our content js and after saving we can see our list although it's not pretty at this point or formatted at all has now been added to the content component inside of our react application before applying css styles i would like to go ahead and replace this delete button with an icon we can use as a delete button so let's go to npmjs.com there you can search for react dash icons and you can look at this package and we're going to use an install command at a terminal window or at the command prompt and here they show npm i react icons and you can copy that right here i'm going to go ahead and click in visual studio code and since i'm on windows i can press control and the back tick to open a terminal window remember you can also go to the menu go to terminal and from there choose new terminal window if you want to as well i just use the control back tick and it opens up the same window that i've been using before instead of necessarily a new window now right now we're running the react app so i'm going to press ctrl c to stop that and i'm going to type npm i react dash icons and then dash capital d and that's the same as a dash dash save so if we scroll down a little bit on the react icons page here you can see they show npm install react icons dash dash save and we can accomplish that same thing with just an i for install and a dash d that represents the dash dash save i'm going to press enter and this will install now this may take a minute to install you can see that mine just completed but what this package is react icons it says it utilizes es6 imports which allow you to include only the icons that your project is using and will use es6 imports such as import and then we'll name the icon and we'll import that from react icons i'm going to use some font awesome or at least one font awesome icon for now and you'll see how we accomplish that so we'll start at the top of the file and just underneath the import use state from react statement we'll say import and add the curly braces and here i'm going to put a capital f and a lowercase a which stands for font awesome and then i'll type the word trash with the capital t and then alt with a capital a so we're getting the alt icon of a trash can and from there i'll say from and then react dash icons slash fa for font awesome and now we've imported this fa trash alt icon and so i'm just going to copy that and we can use it in our code i'm going to close the terminal window again and i'll scroll down here to our jsx and just like we added a component before when we added a header a footer and the content components i'm going to delete this button html i'm going to add our trash icon and it looks a lot like a component we would add this f a trash alt and from here i'm also going to give it a roll attribute equal to button because that's what we'll use it for and i want to include it in the tab index so i'm going to put the tab index equal to inside quotes again 0 and for now we'd be finished with that and i can close out the addition of the icon now i want to go ahead and put these attributes on separate lines like i did with the input once again it's easier for me to read and i'm just kind of used to doing it that way i didn't do it as i talked you through it but this is how i would typically do this and when we come back and add just a little bit more to these components or elements depending on which they are when we come back to add more attributes it will be easier to see where we're adding them when we just do them on separate lines especially if they're responding to a click event as an anonymous function now with this icon added i'm going to go ahead and save the file and if you remember we stopped the app so we won't see that change over here i'll need to open up the terminal window again with a control and backtick button and from here i need to start the app again so i'm going to type npm run start i believe npm start would probably accomplish the same thing i'm just used to typing run and it will take a second but our app is loading in a new window so i'm going to close the old window and we'll see the app show up here on the right in a new tab or a new window of chrome and now we see our application once again the list doesn't look great but we do have trash can icons instead of the delete buttons now i'm going to right click and choose inspect so we can once again have the dev tools open and it opens to the elements tab there we can choose console and i can clear out whatever it's showing that it doesn't like for now and will continue to build on this application my next step is to apply some css to make our list look a little better now it is worth noting as i do this that these icons that we added with react dash icons are svg icons so that will be noted in the css i'm going to close the terminal window then i'm going to press ctrl b to show the file tree once again and from a previous tutorial you may remember that we're just adding all of the css for this project in index.css there is a dedicated tutorial to the different ways that you can add css to a react project and that is the one we've applied for this beginner's project so just below the footer i'm going to go ahead and paste in some css that will handle our list and now i'm not going to go over all of this css but i'll start at the top with just a quick rundown it starts with an unordered list and here i've got styles for that including a before after that we have an item class and we added the class name item for each list item and so the item class applies to each list item and you can see the different things that we apply here and here is the input type check box once again the type check box for a focus and possibly the label where we'll give it an underline if it has focus and then here is some more styling just for the label here's some styling for the svg and once again that svg icon being a button we're applying styles for focus and hover as well and i will provide a link to a repository with these styles in github and i will link to that in the description below so you can copy these exact styles if you want to without pausing the screen and having to type it all in if you don't want to but i want to focus mostly on react rather than css as this is a react tutorial series so i'm going to save this and we should see this apply to our application on the right and now you can see our items look much better we have our nice big check box on the left they are highlighted with a little bit of a different background color and we even change the size and color of the trash cans and they do have a hover and turn red when we hover over them and our mouse turns into a pointer we can also check these and well when they have focus first of all i just gave focus from visual studio code over to chrome when they have focus now it is underlined the label is underlined for the description and we can check the boxes actually the boxes aren't allowed to check yet and the reason the boxes are not allowed to check is back in our content component where we assigned the check status already it's item dot check and that comes from our state and all of these are false so let me just change one to true and save and we'll see the check mark now applied and now we see the check box applied over here so we need to work with the state and we need to do that by adding a handler for the click in the check box let's go ahead and create a function now underneath our use state and we're going to call this handle check and from there it's going to accept the id which is the key of the list item so we have the id property and remember we pass that in as the key for each item and inside of our function right now let's just go ahead and log to the console and we'll log and i'll say key and then this is a template literal and i'll pass in the id so we can see that in the console when we go ahead and check the box i'm going to save this and we still need to add more to the code of course in the jsx i'm going to press ctrl b once again so we can see more of the code and hide the file tree and now for the input with the check box we don't want to add an on click event what we need with the check box is an on change event that we will listen for and now inside the expression for the on change we can't just call handle check because we need to pass in the id and this won't work we need to be able to pass in a parameter to this and this just references the function so this would not help us out what we need here is an anonymous function and now with the anonymous function we can call another function inside of it and so we can say handle check and here just like the key we can pass in the item id just like we gave the item up here when we gave it a list item element and react does need that key but now we also need to pass that same value in to handle check and now that is passing a parameter to the handle check function let's go ahead and save this and now let's test out by checking another box and i'll pull this up so we can see the console a little bit and we got key two notice that didn't change it didn't add a check mark here because we didn't change the state and the state is what's assigned here so right now it's just responding to us going ahead and clicking here like it would be a change event but it's not really changing because as soon as this re-renders and it does re-render as soon as that happens it's once again assigned our state from our default state so we're not seeing the change yet let's go ahead and change our function so we do see the state change so instead of logging the key i'll delete that line and we'll start out with defining our list items and we're going to set that equal to our items and we'll use map so it creates a new array remember we don't want to change the state directly and that would cause that to happen now if you didn't use map and you wrote code in more of an imperative line-by-line step-by-step way rather than a declarative way like with map which is a higher order function you would want to set list items say equal to your current state and create a shallow copy of the array and you would do that like this say this is a new array created from the state items however we're just going to use map and write code in a more declarative way here and this will prevent us from needing to write many lines of code where we can do it all in it's going to be just a little long but one line of code we can say items dot map and we can once again then refer to each item in the list and from there we'll look at the item.id and we'll check to see if it is equal to the id that is passed in with the change event when handle check is called from there let's go ahead and return a new item if the ids were equal so here we can just spread out the item the current item but then we can change the checked let me go ahead and press alt z to wrap this code as it is getting a little long we can change the checked status so we'll have checked and now it will be the opposite of what it currently is if we put an exclamation mark so we have item dot checked but with the exclamation mark in front since it's a boolean it is saying make this the opposite of what it currently is and after that we can finish that item so there is the new item otherwise when this is a ternary statement by the way so we have the ternary operator here with the question mark so we check what we're looking for and that is if the item id is equal to id and then if that is true return this new item and that's essentially the same item but we're flipping the checked status and if not we're just going to return the item that is already existing there and now we in that line so it is one line of code it wrapped it's just a little long but this is using a higher order function map rather than writing imperative code and possibly a for loop or for each loop that would take up a little more space so we're not finished yet but now we've created our new list items array using map and we've altered the item that matches to change the status of it once we've done that we can use our set items to change the state and then we'll pass in the new list items array that we just created let's go ahead and save this much and after that save i'm going to reload just to make sure everything's still running as i expect it to be i'll clear out the console and let's try to check an item and see what happens now the check box works and maybe we can uncheck the other item yes and we're changing the state now now this one has focus so it's underlined now if we give this one focus it is underlined and so everything is working as we expect it to there let's check the state and we can do that in react dev tools again by pulling up the components and i'll give just a little more room here for this and here's the content we scroll down under hooks there's our state and now checked is false for the first one checked is true for the second one checked is false for the third one now let's go ahead and check the third one and see if the state changes in the hooks below and yes now it's false true true now it's important to note that this is not changing the default state of the app and we still have or the default state of the component pardon me that we still have here in our code so if i reload the application it's going to come back to being true false false and we can see that here when i click reload on the browser now it is true false false and we'll see that reflected as well in the state of the application or the state of the component here that's true false false also now we can change it but we're just not saving that state and bringing it back when the application loads yet that said let's get part of the way there by adding one last line to our handle check function and to do that i'm going to use local storage if you're not familiar with local storage i'll give a link above and in the description below for my tutorial about local storage in javascript here we're going to set an item and i'm going to call this item shopping list and from there we're going to use json.stringify and we will stringify our list items and that will be saved under shopping list in our local storage and i'll save that we won't see a change in the app right now but when we do make a check that means we're saving this to local storage and we'll be able to pull that back later instead of pulling back this default state that we have right now with our handle check function complete let's look at our jsx again and let's add a little bit more to the label element to make it interactive as well i'm going to put a space and return and return one more time so we can put the attributes on separate lines and i want to start by adding a on double click listener for the label and we're going to set this equal to the same thing we did for the on change event of the check box and i will paste that in and you can see we pass in the item id and it's going to call the handle check so now when we double click the label we should get the same result as if we checked the check box so i'll save this and we can test this out by double clicking item 2. and yes that works double click it again and it unchecks the same for item one and so our double click is working i want to add one more attribute to the label element and here this will be style equals we're going to set this equal to a ternary statement so we can start out with item dot checked and this is essentially saying if it is true and now we'll provide the true result we will set the text decoration and here we have to put this in quotes we'll put line dash through and then if it is false we can just set it to null and that will set no style at all so let's go ahead and save this and now we can see if we check a box we get a line through the description to show that it is checked if we uncheck it and it has focus it's still underlined but it's only drawn through if we've actually checked the item with that complete we are now ready to add the function for deleting an item so let's scroll back up and underneath the handle check we'll define handle delete and this will also receive an item id now inside this function for now let's just go ahead and put console.log and we'll just log the id we can save that and let's scroll back down to the jsx and look at our react icon fa trash alt that we see right here this icon does have a button roll so here we will listen for a click event with on click and let's set this equal to an expression and now once again we can't just put handle delete here because we need to pass in that item id reference so this also needs to be inside of an anonymous function so we'll start out with the operators and the arrow and then handle delete will also receive the item dot id we can save that and if we scroll back up and look at the handle delete it's just going to log the id for now and now that we've saved this let's go back to the console in dev tools i'll clear this out and let's go ahead and click the trash can and we get three or if we click the second one we get two so it's working as expected now let's put the details of handle delete inside the function we'll start by scrolling back up and highlight the console log that has the id and delete that and now let's go ahead and once again define the list items inside the function and now instead of map we're going to use another higher order function called filter so we can have items dot filter and now inside of this we'll work with each item and from there we're going to see if the item id is not equal to the id so we put item id and then the not equal they strict with two and the id and what's that what that is going to do is create a new array once again if you're not familiar with how filter works not only refer to mdn but also my higher order functions tutorial but this will create a new array that has filtered out the item id that is equal to id so in other words the new array will only have ids that are not equal to the item id that we pass in and that defines list items after that our handle delete function is just like our handle check function so we'll set the state with the list items and we'll also save that same change to the shopping list that we have saved in the local storage so now we can save this and if we go ahead and click one of the trash cans over here now we should be able to delete an item so let's go ahead and give it a try on item two and yes item two is gone how about item three that also works and if we delete the first item now our list is empty notice we don't get a message if the list is empty maybe we should change that too let's look back at our jsx and i'll scroll up so we can see more of this in the window below the main element and before the unordered list starts let's put an expression and in this expression we're going to check the items dot length and we don't really need to say if it's greater than zero if it's zero it would be equal to false so we can just say if items dot length and put our ternary operator and then let's go ahead and put the opening parentheses as well but we don't want the closing parenthesis or closing curly brace right here now let's take our full unordered list and highlight all of that and tab it over and add a line underneath the unordered list and come back and we can put our closing parentheses and now we can go to the false part of the ternary statement so another opening parenthesis here i'll add a line between and now we can put our message if there are no items if items has no length or if items is equal to zero and here i'm just going to put a paragraph and set a style attribute now this is a curly brace but remember if we directly set an inline style we have our curly brace to say this is an expression and then we need another curly brace to say this is a style so here this is going to be margin top and we'll set this equal to 2 rim and give a space there after that we can go ahead and put the closing or greater than symbol for the paragraph and put our message here and we'll just say your list is empty okay now when we save this oh we need another closing curly brace as well here to end this expression so that is the full expression that starts way up here on line 37 and then it includes the unordered list if true but if false it includes includes our empty list message once we save this we should see your list is empty in our content section over here let's go ahead and save and yes it says your list is empty now when we reload we're going to go back to our default state though so we should have our items back because we haven't put in any loading state yet or we haven't really decided to load our state from the local storage yet so right now when we reload the application we get our items back as that default state is set but after we delete every item we should see your list is empty i don't want to eliminate our default items just yet because we haven't added the form to add new items to our list and before that we still need to learn about props and prop drilling in react and that will be in the next tutorial because some of our other components may need to access properties from our list and right now it's solely contained within this content component and we need to share some of this data to other components that's coming up in the next tutorial today we're learning about react props and prop drilling props as you might expect is short for properties and properties hold data and prop drilling allows us to pass that data down from parent components to child components you can see on the left i have visual studio code open and i have the app.js file open right here that shows the parent app component on the right i am running the react application that we have slowly been building through this tutorial series it's a groceries list one thing i notice right now is the list we completed in the last tutorial is still centered here so just for my peace of mind let's go to the index.css file find the main element and in there under the justify content setting instead of center let's set that to flex dash start and save the file and that should take our list to the top and build it from the top down which what you would normally expect okay back to the app.js file you can see we've created three components a header content and footer components we're going to work with the header first and we want to work with props inside the header if we look at the header js file that contains our header component it's very simple it has a header element and inside of it it has an h1 with a groceries list now back in the app.js file we can take the header component that we've listed and we can pass something like title we could really name this anything we want to but we're going to pass title and just make it a string and here we'll say [Music] groceries instead of groceries list just so we know it's different and we can save this and now in the header js file remember this is a component function so we can pass in props which is what is expected the props come from the parent and now instead of the groceries list title here we can put in an expression and we can say props dot title as the props hold all the different properties from the parent component that have been passed to the child component and now when we save we should see our app update and it just says groceries it is using the props title now there is something we can do here instead of always referring to props as well and if you're familiar with destructuring in javascript this will be easier to understand because instead of the word props we can just use curly braces up here and destructure the props as they are passed into the functional component so then we can just say title and then we can get rid of the props dot and this will still work in the same way and you can see it still says groceries after we saved now if we come back to the app.js and we change this to grocery list and save that's what will be passed to the header component and now it says grocery list back here in the header js file and we've destructured our title now we could once again have props in here and have props.title but we need to discuss default props default props allow us to set values for the props expected in the component and if those are not provided then the default values will take over instead of receiving an error and this is great to do when you're speccing a component in other words when you're first designing the component and maybe you're not receiving the data from an api or even a local storage list like we have right now we're using some spec data already but just for this example we'll have the default props of the header and here we can set the title to default title and we'll save this and we won't see any change yet because we're still providing the title from the parent let's go back to the app.js and let's not send a prop called title and we'll just save this without and now we get default title here the component expects a prop and when it doesn't receive it it uses the default prop if we put the prop back in that says grocery list that will override the default and now you can see grocery list again here in our application now that you have a general understanding of what props are and what prop drilling is from working with the header component we need to look at our content component and our footer component what i would like to do is list how many or at least display how many list items we have like a total count in the footer so footer needs access to the list items but they're all stored in the content component and these are sibling components we can't just reach over to the content component and get the data that we need so we need to take some of that data that's in the content component move it up to the app component and then drill it down to both content and footer so let's look at this content component and you can see we have a use state item here with items and set items and right now we have some default data in here for the default state and what we need to do is take this and i'm just going to cut with control x in windows at least but cut this data and i'm going to go back to the app.js and i'm going to put it here instead of having it in the content js or in the content component so now we have items and set items however that is what is expected in content so we need to add that here and we can tab over and have items equals and then set this as an expression and have items and we can have set items equals set items as an expression and we'll bring that over so that's all lined up so now we're passing in both pieces that we use with use state we've got items and set items being passed to content but that's not all because handle delete and handle check these functions also need to access those items as well and so what i'd like to do is pass those down rather than keeping them here so let's go ahead and select all of these functions and cut those out and we can also drill functions down inside just just as we do with other data so we'll take this and paste those in and now that we have that as well we need to go ahead and tab this over it looks like to me we'll take this and highlight all of this and i'm going to press tab one time there we go and now that we have that we're also ready to pass down handle check and handle delete to the content js so here we have handle check and this equals handle check and then we'll do the same with handle delete and we're passing all of this down to the content for now okay so we're passing all of our props down we're drilling those down to the content js and now in content.js since those are missing and get rid of these blank lines we need to go ahead and de-structure right here and let's think about everything we're receiving we've got items set items handle check and i'm going to press ctrl b to hide the file tree for now so we can see more code and then one more comma and handle delete and it looks like we don't need the set items i can't see where it's being used except in these functions so we can go ahead and delete set items i was wrong in providing that i'm going to save this we may get an error right now and we'll come back to the app.js and we'll remove the set items that's being passed down and we'll go ahead and save our app.js and we've still got an error it says use state is not defined in app.js and that's because we're not importing it up here so we need to import use state from react at the top of the file [Music] and we go back to it says use state is not defined again but we did just define it let's go ahead and reload there we go and now if we go back to the content js we can actually see use state is not being used here so we can get rid of that import line at the top of this file and we'll go ahead and save that as well now our app seems to be functioning as normal we can check uncheck everything is responding we can delete an item and so our functions are working but they're all being passed down now to the content js file through props and prop drilling so here we go we've destructured all three of those and then we can refer to them and back in the app.js they're all held in this functional component and they are passed into the content js here now this also allows us to refer to the items that we hold in state in the footer component as we address the footer component remember where i said we could essentially name this attribute that passes down the props anything we want to so they won't always match if we don't want them to and this is a good example of that i'm going to call this length and now what i pass in won't just be something named length it's going to be items dot length i'm getting the length of the array that we're holding in state and i'm just passing in that value so i'm going to go ahead and save this it won't change anything yet now let's press ctrl b to show the file tree just long enough to click on the footer file i'll press ctrl b again to hide it now instead of this copyright message so we can get rid of everything about that i want to display how many items we have here in the footer so i'm going to start out with that value that we receive length which is a good reminder that we need to destructure and receive length here into the footer component at the top and now after length i'm going to say list and then i'll say items now i'm going to change this i'm not quite finished but i'll show you why so let's save this much now you can see we have three list items in our application but if i delete one and two now i have one list items i don't like that i'd rather have it say one list item when there's only one so let's go ahead and change that and we can do that by putting in a expression right here and we'll check the length and if it is equal to one a strict equals we'll just return item and then we can have our false part of the statement and we can say items and then we'll end that expression with a curly brace now let's go ahead and save we have one list item now i should be able to reload and get all of our items back because we're not loading those back from local storage yet so our changes aren't permanent this always goes back to the default state but you can see we have three list items with an s two list items with an s and now one list item now if i get rid of all of the list items we have zero list items and that's okay i don't mind the s with the zero but if we have one i would just assume it just said one item now that we've finished making the change to the footer we can go ahead and make a change to the content as well and that'll be through abstraction so let's go ahead and show the file tree again i press ctrl b to do that and let's look at the content js i think we can use some abstraction and create a couple of more components maybe a reusable component that can declutter a lot of what we see here i'm going to close this terminal window at the bottom as well now as we look at everything that we have in this content js and it's a little bigger than the other files all this jsx remember we have this so it gives us a your list is empty message if there are no items if that items array that we hold in state is empty otherwise we get this unordered list we can really take this unordered list and make a separate component called item list so let's do that now i'm going to press ctrl b to show the file tree and from there i'm going to click the new file icon and i'm going to call this file item list with a capital i and capital l will be js now i'm going to press ctrl the alt key and the letter r and now i should be able to type underscore r a f c e and yes we get our shortcut to creating that functional component and this is because we are using an extension that is es7 let me look at the full name of that we went over this earlier in the tutorial series but i just want to mention the es7 react redux graphql uh all this native snippets so look for that by d s z n a j d e r i'm sure i would butcher that pronunciation if i even tried it so now we've got our item list component and we'll eventually want to import a component in here but right now we can just leave that at the top and our item list is going to receive a few things as well that we are pulling in from the other component let's click back to the file exploration here i'll close up the open editors but we'll look at this and we want to look at the parents so the parent is content.js and i'll press ctrl b to hide the file tree so i can see a little more but what all are we using here we have items handle check and handle delete i think we want to pass all of those on down to our unordered list so because that's where they're being used so we've done that and now back to the item list file we can just paste those right in here as well so they're being passed down and then passed down again again prop drilling so we're drilling down from a parent to a child and now from that parent down to the next child so two levels at least back in the content js we can just copy everything we have right here the unordered list actually let's cut i'll just press ctrl x we just cut all of that out and now we can paste it and again we don't need the divs i much prefer semantic html if possible avoid the divs when you can and paste in this unordered list that we now have here and i've backed it up with a tab there i'm pressing the control tab i believe or maybe shift tab which was that let me look real quick shift tab so now i can tab that back into place shift tab if you want to change the tab backwards and tab of course if you go forwards all right so we've got our unordered list in our item list js we can save this change we're exporting the default item list here so we're going to need to import this now into the content.js and of course we're going to need to do a few other things too so let's import into to import item list from dot slash item list into the content js we can save that but we're going to see an error we need to put our item list component into the jsx so we have item list and now on a separate line let's go ahead and pass down these props so we have items and we need a curly brace there equals items and then on the next line i'm going to do handle check equals handle check and on the next line handle delete equals handle delete and now with that complete we need to go ahead and close out the component and now let's save and see if it reformats i'm using the prettier extension that formats my code so that's why you might see some of those changes there i want to tab this in just a little bit and save again no it wants to move it back out and now you can see we still have an error but it's not really a problem with this file other than we've moved our react icon one component down so instead of this import statement here at the top of this file where we can save content.js in the item list now we need to import the icon at the top here so let's do that and save got another error but i'm going to try to reload to see if we can catch up and not have a problem and there it's fine so sometimes if you get an error just go ahead and reload one more time to allow react to catch up now we've got our trash icon imported here into our list and we've got a separate list component that is building out our list if we look back at the content component it's much more organized now and we can really see the logic in this ternary statement we have here if we have linked to the items array then we display the items list and if not we display the list as empty message just for my piece of mind i'm going to delete this extra line we have with the curly brace at the end i think it looks a little bit better like that i'm going to save it's essentially the same thing it just looked weird to me the other way i've got an extra space here too with the main element and now that i've completed those for peace of mind we're ready to look at making a reusable line item component let's go ahead and show the file tree again and think about the tree or the component tree as we drill down we started with the app component which is apparent and then we move down to the content component so from app.js to content.js and then to item list js we're going to go one more level as we create a line item js so let's click new file and line item js with a capital l and a capital i and this will be a reusable component that we use for every line item so once again press the ctrl key the alt key and the letter r if you're on windows at least and we can do underscore r a f c e and we'll create this reusable line item component now learning from our previous mistake if we go ahead and jump back to the item list component we can copy our import of the icon because we're really going to need it in the line item instead of the full list so once we have done that we can add that import at the top of the file so we don't get an error in the future from that and then we can still go back to the item list now let's go ahead and hide the file tree to have more room by pressing ctrl b now everything that we see inside the map as we map through each item creates this line item so we can take all of this and cut i press ctrl x on windows kind of like copy but we're cutting it out and we're going to paste it in here in the line item and again i'm replacing the div with an li for line item and i'm going to tab this over so it lines up right for me there we go so the full line item and now of course we'll be importing the things that we were using in the item list js we do use items here but we need to go ahead and send all of these on down through the component tree to the line item component because we'll be using all of them here as well so now that we've done that we can save this and it looks like we're not using items but we are going to use item because this is an individual line item so let's go ahead and provide item to pass down so now we know we need the individual item and we still need access to the handle check function and the handle delete function so this is what we'll be passing down to the line item component every time it maps through an item so we'll save this file and it's exported as line item we'll go back to the item list and we need to import line item and that will be from dot slash line item and now that we've done that we need to create our line item component here in the jsx and now we need to pass the props down to the line item so let's start with item as that is generated from map as we map through the items so we pass in item as an expression item equals item from there we're also going to pass in handle check which should equal handle check and handle delete which should equal handle delete but we're not quite finished yet this will still cause a problem oh and we also need to close out the component or we'll definitely have a problem but this is still a problem i'll go ahead and save and i'll see if it identifies it in the errors here in the console scroll this up choose the console and yes we have an error let's look at what this error is and each child should have a unique key prop that's what we need here each child so we need to supply the key so let's go ahead and do that for each line item right here and we'll set the key equal to item dot id now if we save that our error should go away we'll go ahead and reload and no more air and we've created a reusable component for each item in our list so all of these pop props are passed down and oh and we can get rid of this import for the trash icon we already have it in the line item component now but the items handle check and handle delete are passed into the list and then we use those except items is mapped through so it generates item so the line item component gets item instead of items but it still gets the handle check and handle delete functions passed down as props as well and then we can see those here in the line item so we have more files but it's very organized and very specific it's a little more abstract but it's also very reusable and we definitely see that with line item as this component is used every time we add a new item to the list just one more quick adjustment and that's just something i see missing from our trash icon buttons since it's a button but it's an image we need to add an aria label here and we're going to just set this equal to a expression that will hold a template literal and we'll say delete and now we can refer to each specific item so there it just says delete item.item just like we have in the description and that provides an aria label for accessibility for our trash can icons so if we save that we've progressed quite a ways in this grocery list project and we will continue to move even further is in the next tutorial we'll be adding new items to the list and loading the items that we've saved from local storage as well so we'll be working with controlled inputs in the form input state today we're talking about controlled components but that is a little misleading uh the name can be confusing for beginners controlled components refer to inputs in react forms forms in reactor handled just a little differently and the inputs are controlled we try to use one source of truth for the state and we'll get to that in just a moment i want to go back and do just a little bit of setup and clean up from the previous tutorial that we had on props and on lists and keys if we look at the package.json for the project we've been working on which is the grocery list i'm running here on the right in chrome we can see the dependencies listed but when we installed the react icons dependencies back in the list and keys tutorial i accidentally installed those as a dev dependency so we need to move those you can go to the terminal and choose a new terminal or like me in windows you can press control and the back tick to open up a terminal as well so we're going to continue to keep the react icons we just need to move them to being a production dependency i'm going to open a new terminal because i'm already running react in one terminal and here i'm going to type npm i and then react dash icons then dash dash save dash p r o d and this will move it to a production dependency instead of being a dev dependency i'm going to press enter and with that finished i'll go ahead and close the terminal window and now you can see our dev dependencies are empty and when we scroll up in the package json react icons are listed under the regular dependencies for production and that's where we need them of course we're running dev over here as we develop and so it didn't impact what we were doing i just wanted to correct that also from the props tutorial we went ahead and in the item list we're adding the key as we should for each line item right here but because i pasted in the list items into the line item component we had previously had the key here again it didn't keep anything from running it didn't cause an error but in the line item component you can remove the key attribute from the list item element here and that is because we already have it for the line item component right here inside of the item list component and this is where we map through and list each line item so with those changes saved we are ready to move on towards controlled inputs i'm going to go ahead and click on the app.js and again our application is running here on the right in chrome and we have a grocery list we can check items and we can even delete items we're still using the default state so when we reload we get everything back and the main reason we're still using a default state instead of pulling those items in from local storage where we have been updating them after we also update the state the main reason for that is because if we did that we have no way to add a new item we could delete them but we couldn't add them back so we need to add a form to add our new items and we'll do that with a new component called add item so in the file tree we can click the new file icon and create add with the capital a item with a capital i dot js and we're using the react snippets extension that i have also linked to in the description and shown in previous tutorials if i press the control key the alt key and the letter r at the same time we can type underscore r a f c e and press enter and we get our add item functional component now we just need to turn this into a form instead of a div so we'll change this to a form element and let's go ahead and give this a class name attribute and we'll set this equal to add form with a capital f now inside the form we're going to have a label attribute and here we'll have an html 4 attribute with a capital f and that's because we can't use the regular 4 attribute like we would in html 4 is a reserved word in javascript and remember all of jsx is a javascript or is javascript so here we'll set four to add item and after that we're going to go ahead and add the label here and we'll also say add item we'll probably hide this label off the screen but screen readers would still be able to read it and you always want to have a label for every input on your form now for the input i'm going to put each attribute on a separate line and we'll start with auto focus make sure that f is capitalized in auto focus and then we'll have an id and i'll set this equal to add item after the id we'll set the type equal to text and after the type we'll have placeholder we'll once again say add item if i could spell item it would help after that we'll make this a required input and then we'll wait on the rest we will come back and add a couple of extra things in just a little bit we're also going to have a button and i'll also put these attributes on separate lines the type is submit which should be the default type when it's the only button in the form but i'll go ahead and explicitly say that then we'll add an aria label aria label is one of the few attributes that even in jsx still has the hyphen instead of using camel case and here we'll say add item as well and that's because we're going to use an icon instead of using lettering or words on the actual button itself and close the button and there we have the closing button tag as well but now we need to go ahead and import that icon from react icons at the top so we can use it on the button so we're going to import f with a lowercase a plus with a capital p that means font awesome plus this will be from react icon slash fa put a semicolon and go ahead and save that but we need to put the fa plus icon inside the button as well with that complete we can see we are exporting the add item component at the bottom so let's go back to the app.js and just underneath the header let's import our add item component from dot slash add item we can save that and let's add it to our jsx below just underneath the header we'll add our add item component we'll save and it should show up and it does and it is ugly right now it is not styled at all but there it all is so now i'm going to put in some css to go ahead and add the styling we're keeping all of the css in the index dot css that you see here in the file tree and again it is not the driest because i did create the css on a per component basis so you could actually pull all of this css out and create separate files for each component if you wanted to now i'm going to link to the full source code in the description below so you can copy these styles out but i'll quickly go over it here's the form and it is a display of flex and so that gives us a little bit of control there besides that it just has margin padding and border i've taken the label and set it way off screen so screen readers can still use it but we won't see it the import or the input in the form has a flex grow style of one so it can grow and fill out the space we expect it to other than that inputs don't get all of the font styling and sizing that the other elements on the page do so i go ahead and add some of that here as well along with border radius we've got a button here again padding border radius minimum size 48 pixels high and a minimum width of 48 pixels and that's because that is thumb or finger size you don't usually ever want to go smaller than 48 by 48 cursor is a pointer we've even got some focus and hover styles but nothing too unusual i'll save that and we should see the changes and now our add item input is nice and big we've got a submit button that turns green when when we hover over it and it's ready to go as well now to make this a controlled input we need to tie it to state we want to have one source of truth for the input and we want to change the state as the input changes as well so back in the app.js i'll scroll up here and we have our default state here for items and set items so just underneath that i'm going to define new item and set new item and of course this will also use state and i'll just set that to empty quotes inside so it will be blank to start out with we can save that and i'm going to go ahead and press ctrl b as in boy to hide the file tree for a moment so we can see more code and then i'll scroll up because we also need to define a handle submit function that is going to handle the submission of the new item so we'll call this handle submit now this function is going to receive the event object and right now inside here i'm just going to go ahead and log and we'll say submit it and once we've saved that we need to pass our new state and the set new state new item set new item and handle submit we need to pass all of those down as props to add item so with that said let's go ahead and do that we'll have new item equals new item after that we'll have set new item equals set new item and then we'll have handle submit equals handle submit we can save that now i'm going to press ctrl b to show the file tree once again go to the add item component and here we need to destructure these props as they come in to the component so we had new item set new item and handle submit i'll save that and press ctrl b to hide that file tree again and now let's make the input a controlled input or controlled component to be accurate we're going to do that by setting the state to be the one source of truth for this input and we can do that with a value attribute and here we'll just put in the state so it's new item but if we just left it at that we wouldn't even be able to change the state at all or change the new item so we also need an on change and here we're going to actually pass in the event object and after we pass in the event object we need the equals to create an arrow we're going to call set new item and here we'll have event dot target dot value so now as we type in this field it will set the new state for new item and that will be represented there as well so because not only because we typed it but that would be the state so i guess i could set another place to display the state or we could just look at the state in the dev tool so i think that's what we'll do let me right click and choose inspect and now with dev tools i need to go to components bring this up and now let's find the add item component and we'll look at the state here it is it's an empty string right now for new item but we'll start typing here and we have let's say s t a t e and it catches up just a little bit behind my typing but there is new item state right there or we could say we're shopping for pizza and now there is our new state right there in the dev tools and i'm using react dev tools to show the components again a link in the description for those but we see the state update automatically now does this update our list no we still need to handle the submit but we are handling or we're linking to one source of truth for this input it is now a controlled input i'm going to get out of react dev tools and come back to the elements in dev tools for just a moment so you can see these elements here and of course as i mouse over things change but really this is still in html form and as you may know when you submit an html form it reloads the page and i believe i've saved this file so just to verify this when i press enter oh and i made it required so it says please fill out this field okay i'll type in pizza and press enter and you see the elements flash here watch the elements section of devtools i'm going to do that again i press pizza press enter and it reloads the page we want to prevent that behavior and we can do that by preventing the default behavior of the submit event but we're not going to do that right here on the submit because we need to call the handle submit function that we have passed in you may see some actually explicitly pass in the event with an arrow function like this and then they're calling handle submit inside and passing in the event like that but you don't really need to do that the event is implicitly passed without you explicitly showing that it is so handle submit here will still receive the event and we can work with it as we define the function so i'm going to save this since we've passed handle submit into the on submit listener here for the form and now we'll go back to app.js and we can define this function right now it has a console log submitted let's go to the console and let's go ahead and type in pizza and it's flashed submitted but then because of the page reload we didn't see the word submitted so we need to stop that page reload first we can do that by taking the event and then put a dot and put prevent default and call that first in the handle submit function and then we should be able to see this submitted and it won't reload the page so now if i type pizza we get submitted in the console pizza is still here because the page did not reload because we used the required attribute in the input we really should not get a blank value submitted but we can check for that to say if we do not have a new item in other words if it's undefined or false then we can just return and exit this function altogether after that we do want to call an add item function that will define and from there we're going to set the new item and we will reset the new item to empty as it was before because we don't want to continue to have the pizza there so now let's go ahead and reload and try this again we won't see this submitted since i removed that but if i put pizza and then we press enter it submits and then the state is set back to empty so we don't still have pizza there to verify that we're receiving pizza we could go ahead and log the state here before we define the new item and then or before we define the add item function and then we'll know we are receiving that so let's go ahead and save that and now we'll try again i'll type in pizza press enter it disappears there but we did get pizza in the console and this long line here is kind of making pizza wrap but we do see it now let's go ahead and remove that console statement but we need to define the add item function so we can call it in our handle submit we'll scroll up above the handle check and handle delete and we will add item right here so const add item and this is going to receive an item of course whatever the new item is and inside here we need to think about how we're constructing this item and we can see items have an id and then they have a check value and then the item itself so id is the first thing to concern ourselves with and how do we increment the item id let's go ahead and write a little code that does that we'll define the id here and let's set it equal to checking if the items which is our state our list length so if we have length if it's not zero is essentially what we're saying i'm going to press ctrl b again to give us some more room and hide that file tree and this is a ternary statement so if there are items in our list our current state then we'll look at the items and we pass the items dot length minus one and by referring to that this should be the last item in the list remember length starts at one and tells us how many items but when we're looking at the position of an array it starts at zero so we always have to take the length minus one and there we'll get the id of the last item and then we'll add one to it so that increments the id by one and that can be the new value however if items has no length that means it should be zero and then we just need the item id to be one so there is our ternary statement that sets the id value and now let's define this new item [Music] and maybe we should call this because we're also working with a new item state let's call this my new item just to make it a little more clear that we're working with something differently and this will be an object so we have the id checked will always be false when it starts and then we're going to have the item that's passed in and there is our object for my new item now we need to create that new array to update the state with so we'll call this list items and set this equal to and now we'll use spread operator here for items and then we'll also have my new item at the very end and that is our new list and then we can just update the state now when we do that it's just like the handle check and handle delete functions and notice this function handle check and handle delete both have the same lines at the end the last two lines and i've copied those and we can paste those in here but that's not very dry is it because we're repeating these same two lines in every function it would make much more sense if we just broke those out and created a function that we could call every time so let's do that i'm going to copy those and just above we'll create a function and we'll call this set and save items and then we're going to pass in the new items and now let's just put those two lines right there but here instead of list items we'll just have new items and we'll change the same thing here and then in the rest of these we can instead of saying set items we can say set and save items and then we can just remove the local storage line altogether and we'll just take this one line here and replace the last two in each of these functions i can actually select them both and paste in and save and there we go now we set and save items at the end of each one of these functions instead of having those two lines that were identical in every function now let's go ahead and scroll back down to our handle submit where we're ready to actually call the add item function and we'll do that with the new item state and save and we should be ready to add new items to our list i'm going to clear out the console and reload just to see if we have any other warnings or errors but no everything looks like it's handled all right now let's try to add some new items to our shopping list and i'm going to add pizza and it works that's great so let's add almonds and chips yes and we're getting our new items and now if we delete an item it still works it's all good we could add milk to our list everything seems fine but right now we're still using that default state so when i reload we're back to these same values but now that we can add new items let's go ahead and start loading from the local storage and remove this default state now if we scroll up we can see when we save we use json stringify with local storage to set that item we need to go ahead and remove this default state now and we want to pull the values out of the local storage that we have saved so let's start out with json.parse and then we'll have local storage dot get item and then we can specify the shopping list that we saved the items under in local storage we'll save that and now we've got milk and bread that's what i had currently in the local storage under shopping list so i can delete all of those now and we're not worried about running out of items because we can add more items back in so we can say pizza milk bread and then we can say something like almonds chocolate covered unsalted you know the ones in the blue bag and that works as well so we can add as many items we want we can check those and we can remove ones whatever we do and then when we reload that same state should come back in from the local storage and it did right when we reloaded i can do it again and nothing's changed the check item remained checked the items that were here remained and the items that we deleted are no more okay let's go ahead and close dev tools and while this is great i want to implement one more form that will work just a little differently and let's acknowledge that grocery lists can get very long maybe we're looking for a specific item in a longer list so let's add a search to our grocery list and we could add a few more items as well and then we could just narrow down those items when we just want to pull up the one that we're looking for at that specific time i'm going to press ctrl b once again to show the file tree over here and we're going to add another new component and we'll call this search item.js okay our search item component is also a functional component so we can press ctrl alt and the letter r and then type underscore r a f c e and that gives us the outline of our functional component this will also be a form just like our last one was for add item so we'll type form first let's give this a class name set it equal to search form and now for the on submit this will be just a little different than before let's press ctrl b to see more again hide that file tree our on submit listener here is just going to handle that prevent default right away so here we'll pass in the event and we'll say e dot prevent default and that way when somebody presses enter we won't even have a button for this form but when somebody presses enter it won't reload the page so there is our prevent default with the on submit from here we can add a label and inside the label we'll have another html4 and we'll set that equal to let's just call it search and then on the label we'll say search and again we'll probably hide this label off the screen and we'll just use the input let's put the attributes for the input all on their own line we'll have an id equal to search and a type is going to be equal to text i'm going to have a role for this and that's because it's a search box so that gives it the proper role as far as the html is concerned placeholder we'll set this equal to search items so we can search our list and now the last two once again we won't put in right away so let's just save this much we don't even need a submit button for this form because it's going to handle the search just a little differently whereas when we create a new item we didn't want to add it to the list until we completed typing our item but in this case we want to start searching right away as soon as the user begins to type let's go back to the app.js i can just click on it up here at the top and we're once again going to set state so we'll set search and set search and we'll use state here as well and we'll just once again set those to empty strings to start out with or set it as an empty string to start out with so we've got search and set search and that's what we will want to pass to the new component oh and we need to import that as well right so underneath the header once again we can say import search item from dot slash search item and after we've imported it then we can add it to our jsx here we'll add search item and we're going to pass in the search it's equal to search and then we're also going to have the set search equal to set search and after that we should be able to close it out and save now once again we see our search input and label up here in our application but it is not styled so i'm going to press ctrl b and go to the index.css and scroll down to the bottom of our index.css to paste in the new styles for this search box again these styles can be broken out just like i had mentioned before per each component so you could have separate files so this will not seem as dry between the form styles but once i save this we can see our search items input spans the entire application here we don't need a button because we're just going to be able to type and we have linked that together and if we look back in the search component we still need to link it to our state that we have set and we'll need to destructure that as well so let's receive the search and the set search with the destructuring at the top of the component and then inside of the input we can set the value equal to the current state of search and then we also want the on change and now here is where we will pass in the event to an anonymous function and then we will set the search and we're going to set that equal to the event.target.value and then i want to come back to the app because i believe i put these in the wrong order so i want to put the search item actually i'll cut that out and i'm going to put it underneath the add item and now save the app and they've flipped rolls and yes that's what i was picturing more and that's spaced better the way i had set the margins so the ad item is on top other than that i didn't make another change there but now being tied to the state when we search we could once again look at the components in the dev tools and i will scroll up just a little bit we'll pick components out of our react dev tools pick search item and there we can see our search state so when we type in piz we will see that represented in the state below we're just not filtering the list yet at this point so we need to go ahead and put our search into action but we are getting the search state now and now that we have the search state i'll go ahead and close the dev tools once again and i'm going to press ctrl b to see more of the code and now we can filter the items that are passed to the content component and that will essentially apply what we type into our search box and it will filter the items to that so let's do this with the higher order function filter so instead of just passing in the items we want to pass in items dot filter and from there we're going to have an item and now inside the filter let's put two of the parentheses and then we'll have item.item which is the description and that does need to be inside parentheses because we don't want to think this is another part of the object so outside of that then we can put two lower case because we know we're working with strings in that field and now let's close out that parentheses so to lower case and then we want dot includes and from there we're going to say includes the search state and i am wrapping the code to the next line to lower case also because that would get it to match so if we didn't put the too lower case then a capital m would not match the lowercase m the capital p in pizza would not match the lowercase p but i think it's better that we go ahead and just set everything to lower case for the match it won't change what we see on the application or it won't change our state this is just a conditional here so if we go ahead and save that now it already applied and it's showing pizza and if we remove that search now it shows everything again or if i type just b we get bread but there's also a lowercase b for blue and bag in this so it narrowed it down to both now if i type ba it should just match with bags we're filtering each one of these z is just in pizza r e a d is just in bread or even just r e a so our search items box that filters the items we're passing to display in the list is also working so just a quick recap on what we've done for our two controlled components today add item has the value equal to the state and then on change we set the state with e.target.value and then it's very much the same with search item we set the value equal to the state and then on change we once again set the new state to e.target.value and that gives one source of truth for the input and that is the state and that's how you want to handle inputs in a form in react let's go back to the add item.js and there's one final addition i would like to make before we finish let's notice if we add something new here and let's just say we're going to buy sushi at the grocery store but instead of pressing enter i click the button now notice the button still has focus because i have hover and focus style to change it to green i clicked the button the button retained the focus i'm not ready to type if i type an a or a b i'm not seeing anything here and so we need to shift the focus back to the input and we can do that with a hook and react and that hook is called use ref so let's go ahead and import that hook and we'll import that from react [Music] and while there are some other cases for use ref this is by far the most common use case for it so let's just call this input ref and let's set it equal to use ref and after that for our input just after the autofocus let's come down and give a ref attribute and we'll set that equal to our input ref that we defined now we can save that but that still doesn't fix our problem we've applied the ref to the input now and we've imported use ref to use but we're still not setting the focus back to the add item input yet after we click the button let's go ahead and do that in the button click event so here we'll have on click set that equal to and we'll use an anonymous function and then inside that function we'll say input ref dot current because the ref always has the current property so that's what you want to refer to and then dot focus and now when the button is clicked it will set the focus back to the input so now if we put something else in here like crackers and click our button we've got focus back here that was only green because my cursor was still over so i'll do that again and i'll move the cursor just a little faster so let's say soda pop and click the button and move away and focus is already back where we want it to be we've come a long way and we've learned a lot about react while we've been completing our grocery list application but there's much more to learn now we're going to take this to the next level in the near future where we would be interacting with some data from a server or on the back end if you will as react is front end development so that is coming up in this series it is your first code challenge after completing the previous tutorials you should be able to create this application on your own notice there's an empty square that says empty value in it and then there's an input that says add color name and we can click in the input field and we can add any html color name such as aqua or steel blue or well any name we want to magenta or even one of my favorites papaya whip and so really you've just got the input field and the square so a couple of components to create there that are probably nested in your parent app component i'm going to reload so you can get a good idea of what it looks like when it first loads an empty square that says empty value and the input field already has focus now right now you should pause the video and try to create this on your own after you've completed the previous tutorials i really think you can do it but now i'm going to give you the solution and we'll build this together so after you have worked on this go ahead and watch the rest of the video and you can compare your solution to what i come up with and now we're ready to create the solution now remember anytime you start a new react project you want to use create react app and to do that you want to be in the parent folder so i'm in my react series folder and i'm going to create this application under the same naming convention i've been using for the other tutorials now you could name it something else like color changer or whatever you want to but i'm going to type npx then create dash react dash app and then i'm going to name this tin tut just because that's the naming convention i've been using for all of these projects and i'll press enter this will take just a little bit so i'm going to come back when create react app has completed and now with create react app completed and we have the happy hacking message let's go ahead and go to the file menu and we should open the folder that we created for our project so in my case it would be under the react series and tin tut i'll select that folder and we should see that open up here in visual studio code and with our new project folder now open let's go to the source folder in the file tree and we can remove some files i'll select the app.css i'm going to hold down the control key and select other files as well including app.test.js and then the logo.svg the report web vitals and the setup test and then i'm just going to press the delete key to remove all of those files now we need to make some adjustments in the remaining files let's go into the index.js and i'll select all of the comments at the bottom and the report web vitals line and remove that and i can also remove the import line for the report web vitals now i'll save the index.js file and in the app.js file we can remove the imports at the top for the app.css and the logo and then we can also remove everything between the div so all we want is the opening div left that has the class name of app and we can save that as well now that we've made those adjustments let's go ahead and put something in the app just an h1 that says hello and i'll save that and then we'll press control and the backtick or you could go up to the terminal window to open a new terminal but the control in the backtick on windows will open a new terminal as well and i'm going to type npm start to launch the react app and we just should see a blank page that says hello it will take this just a moment and i'll come back as soon as the app launches the default app has now launched and we've got hello over here in chrome in a new tab we can click the other tab and there you see the project that we want to create it has the square that says empty value and it has the input where we can add a color name or a hex value so that's what we want to create and if we break that down in our minds we really need to just realize there's a couple of components that are probably nested within the app component so let's go ahead and get rid of this hello now and we'll create a new file over here and we'll call this square dot js with the capital s for square and i'm going to press ctrl alt and the letter r i'm using a react snippets extension that starts with es7 i've mentioned that in other tutorials and here i can type underscore r a f c e to use this snippet and it creates a functional component it's not that you couldn't type all of this out that's just a shortcut so here we've got our square component and now let's do the same thing and create a file called input.js and i'll do the same thing here too i'll press ctrl alt and the letter r then i'll type underscore r a f c e and again this uses the snippet extension i have the es7 snippets for react and there we see we've got the const input so it's a functional component and we can export that and we're going to import that along with square into the app but for now let's put an h2 here and we'll just say input save that and then in the square file we'll put an h2 say square and save that and now back in the app file at the top we can import both of these we'll say import square from dot slash square and then we'll do the same for the input input with a capital i from dot slash input we can save those and now we need to put those in our jsx so we'll have a square and close that out i have an input with a capital i and close that out and now if we save our jsx we can see our square and our input now let's go back to our square component and we can pass in a prop we haven't passed it in from above yet from the parent but we'll just put it here color value and that's destructured and then we'll turn the div into a section element and this section element is going to have a couple of attributes the first being a class name and that's camelcase with a capital n for name but the class name is square and that has a lowercase s and the second prop or the second attribute i'm sorry is style now this allows for an expression but remember we have to put a second set of curly braces to then pass in the style and here we'll have background color and that's camel case not a hyphen because remember this is still javascript in the jsx and here we'll use the color value attribute that is being passed down and then i'm going to go ahead and put this closing greater than symbol for the section on a separate line and then in here instead of this h2 for the square we're going to have an expression i'll put a paragraph and here we'll say color value and if we have a color value that's what we want to say right here so we'll also spell out the color value but if we don't that would be the faults then we want to say empty value with a quote i'm going to press ctrl b as in boy to hide the file tree for a second so we can see the rest of this then i need to end the expression and so this will type out whatever the color value is if we type in aqua or magenta or whatever but if we don't have a value there it will display empty value okay after that we've closed the section and we're not passing in a color value yet so let's go ahead and give a default prop down here this will be square dot default props equals now we can have color value here and we can just say empty color value so that will be different than the empty value just so we know when we see it we can save that and we're finished with the square component for now now we can go into the input component the input component is going to receive the color value state just as the square component did and it's also going to receive the set color value so we can change the state and again we'll need to add those to the app yet they aren't there after that we need to change this div for the input component into a form and immediately we'll put an on submit right here and we'll handle that submission with an anonymous function that receives the event object and here we'll say e dot prevent default and we want to call that into action right away and if you remember an html form submits on by default and that reloads the page we don't want that to happen so this will prevent that from happening now we can remove the h2 from the input and we need to add a label here as every input needs a label and we'll just put add color name so there's our label and now we have an input and this input is going to receive several attributes or it will have several attributes i should say the first is auto focus with a capital f on focus the next is type and we'll make this a text type attribute and then we'll have a placeholder and our placeholder is going to really say the same thing as our label just add color name and then we'll make this a required input it's really the only input so it needs to be required if we're going to send it on then the value will be the color value and this is how we make this a controlled input and then we add an onchange and here we'll have an anonymous function and inside the anonymous function we can set color value and here it will be e dot target dot value and now that will set the state of the color value to whatever is typed in after that is completed we just need to close out the input and everything will look like it should for now so let's go ahead and save that but we aren't passing these in yet so we really need to work on the app.js file in app.js the first thing we need to do is import use state from react and after we've imported the use state we're going to use that immediately right inside of the app function so then we'll have our color value and we'll have our set color value and there we'll use state and we'll just set the state to an empty string to start out now after that we have to remember what we were passing to each component and for square all we were passing was the color value so this will receive the color value state and input received a little bit more so let's go ahead and give it separate lines and we'll say color value equals color value and then also set color value equals set color value and we can save that as well now we see our changes so far over here in chrome now we haven't added any styles so it doesn't look great but we see our empty value at the top and then we see add color name and we've got our input to add a color name so if we add something like dodger blue it already works it just changes the small area we haven't turned it into a square yet or we could change it into magenta i can spell magenta there it is so the app is functioning as we expect it to we just need to make it look better i'm going to press ctrl b as in boy once again and that will show the file tree and then select the index.css and there's a couple of default styles in here from the default create react app project i'm just going to paste in my styles this isn't a css tutorial but i can go over them with you very quickly and i'll go ahead and save so we see the changes and there is the app like we expect to see it so how did we do this with css well we've got a reset to start out with and then in the html element i just set a default font size in the body i set the min height to 100 viewport units i just pared down the font families that were default in the create react app already i just left roboto and sans serif and a couple of things they already had there the app component min height again is 100 viewport units it's a flex box set to column and everything is centered in the column here's where i built the square it's 400 pixels by 400 pixels has a border a box shadow radius the display is set to grid for the square because then it's easy to just center the one thing that's inside of the square and that is just with place content set to center and then i also aligned or text aligned the paragraph that's within the square the form also 400 pixels wide to match the square the label for the input is set off of the screen so it's still in the html dom and a screen reader would be able to read that that's my typical thing that i do if i'm just using the placeholder for visually labeling but at the same time you don't want to leave out a label you want to include it and then you can set it off the screen if you don't want to see it in the presentation and then the input type text that we select just specifying what type of input it is here in the css and there is the app so if we type in dodger blue it sure works steel blue should work for any of them alice blue old lace all good now i hope you were able to do this and so came up with something similar to what i did because this is applying the use of state and controlled inputs and also passing props down to components a lot of the things we've learned in previous tutorials now there's a couple of things we can do to level this application up so let's do just a little more i'm going to go back to the app component app js and underneath the color value state i'm going to set another state and this is going to be hex value and then set hex value and i'm going to do the same thing here for the default state it'll just be an empty string and after that we need to pass these values down as well square i'm going to go ahead and put the attribute on a separate line because square will now have more attributes so i'm going to pass in the hex value for the square as well there we go can type all right and then for the input it's going to need to receive the set hex value so here will be set x value equals set x value i can save that and now let's go to the square component first and we need to remember to destructure hex value at the top just like we did color value so now we're receiving hex value and what we want to do now is put a second paragraph i'm going to press ctrl b to hide the file tree again just so we can see a little more and here in our second paragraph we're going to have hex value and another ternary statement so if there is a hex value we'll display the hex value and if there's not we won't display anything i'll just say null here in this ternary statement now i need to put a closing curly brace there for the expression and we can save that and then we can go to the input js and in the input js we're going to destructure the set hex value and then we need to use the set hex value and so this on change i'm going to go ahead and put in curly braces around the function and now that i've done that i'm going to break this out onto separate lines and there we go and we'll need another curling brace to close the expression so there we've got the two ending curly braces i've got the set color value and then i'm also going to do set hex value now normally we would just have e dot target dot value here but i need something to translate the color name into a hex value and so for that i need to import another package now to import this package i'm going to press ctrl and the back tick to open up the bash window the control prompt down here but we're already running react in this one so i need to press the plus button to open a second bash window i'm going to type npm lowercase i and then color names all one word all lowercase and then dash s and the s is a capital s which will save it to our production dependencies instead of our dev dependencies and that's exactly what we want i'll press enter and when this finishes we can add it to our project okay the install is complete and color names has been added to our dependencies we can click the trash can over here to kill this bash window or terminal window the other one is still running for react and that's fine we can x out of it and it still works i'll press ctrl b to show the file tree again and click on package.json and here you can see we've now added color names to our dependencies in the package.json okay back in the input component at the very top we need to import color names so we'll type import color and now this will be camel case not all lowercase so import color names from color names which is all lowercase let's do that and so now that we've imported color names we can use it and what color names does is take the name of the color and translate it to a hex for us so now we can put color names right around this e target value once again hiding the file tree so we can see all of that we need the closing parenthesis so we will translate the name of the color to a hex value and then we'll set that hex value as the new state for our hex value state once we save that we should be able to try this out i'm going to come over to the app and here i'll type magenta and here we got the hex value along with the color name in the square and that should work for any color so my favorite papaya whip there is the hex value as well and dodger blue is a good one so that's working as we expect it to what else could we add well if we put in a darker color those text letters or numbers are are hard to see if we put black we just can't see them at all so maybe we want to put in a button that will let us toggle the color of the text as well i'll take out this gray and we'll be back to our empty value here and now in visual studio code i'm going to show the file tree again and click on app js because to do the toggle button we need one more piece of state and here i'm going to say const and we'll call this is dark text because the default will be dark text and then we'll say set is dark text and now this will be a boolean value so for our use state we'll just set it to true we want to use dark text as the default and after we save that much we need to decide where we're going to pass this to well the square is where it will be displayed so it will definitely need to know if it is dark text or not so we'll pass that in to the square now in the input we're going to need to pass in both so we need is dark text equals his dark text and then we also need set is dark text there we go set is dark text and set it to the same and we're passing both of those new values there into the input so now let's go to the square and let's destructure the is dark text at the top and from there let's put this style on separate lines we'll put a comma after the color value and then here the color will be is dark text now remember this is boolean so if it's true we'll set the text to a predetermined dark color and that should be black and then if not we'll set it to predetermined light color and that should be white so there we've set this to a boolean that based on or we've set it to a ternary sorry based on the boolean value we get it will either be dark or it will be light so let's save that and then we can go to the input and in the input i'm going to hide the file tree again and then let's just break all of these props down to another line where we're destruction because we have to add two more and so we'll have is dark text and then set is dark text that will be received in the input and now we need a button to actually toggle these values so we'll start out with a button and it will have several different attributes the first one being type equals button the default type in a form when there's only one button would be submit and we don't want that the second attribute will be on click set equal to an expression and in this expression we will just set his dark text and what we're going to do is set it to the opposite of whatever his dark text is equal to and we can do that with the exclamation mark since it's a boolean so if it's dark we want it to be light vice versa and essentially this is going true or false which is what we're setting and then the decision is made later on now we need to close out the button still and so there's the closing button let's put it back here there we go and then on a separate line we'll have the closing button so on the button we'll say toggle text color and let's save that now we have a very small button here that says toggle text color but we can try it out so let's set this to black and now if we toggle the text color it's white and now if we bring this back and set this to white we toggle the text color it will be black so really all we need to do is still style this button okay to style the button i'll press ctrl b to see the file tree and then we'll click on index.css and just underneath the other styles i'll paste in the button styles and here you can see i'm setting the button width to 100 so be just as wide as the input minimum height to 48 pixels given a little margin on the top pretty much setting the font to be the same size border radius the same same box shadow and adding a little bit of padding in there as well and once we save that the button should look a whole lot better now i'm going to save all of these styles in a repository and link to this in the description below as well so right now let's go ahead and change this back to something like magenta and then see what the text color looks like on each so we can change that everything's working as expected i hope you learned a lot from this project or at least it let you practice the skills that you had already learned in the previous tutorials because sometimes i think that's important to start applying what you have learned and we have a lot more coming up yet today we're talking about the react hook use effect i've got visual studio code here on the left and on the right i've got the grocery list app that we've been building in this learn react tutorial series and the console the devtools console was open here on the bottom right so with that said i'm going to press ctrl b i'm on windows it may be different for mac and linux but that hides the file tree in visual studio code to let us see all of the code i'm also going to press alt z and that wraps long lines of code like you see here for line 9. now you could also make those selections up here in the menu so if you're not sure of the key shortcuts please do that with that said now let's import use effect right after use state and that's from react and after our import statement we can begin to work with it and one of the things we'll do is discuss about when use effect runs so if i have use effect and i just type out the simplest version of it and it takes an anonymous function this runs at every render so here i can put console log and put render right here and we'll save and now we've already got a render and any time i type a letter we'll get another render and you can see it's just counting now in dev tools as we see here so every time that the component renders use effect is running over here now we don't want that to happen most of the time usually we need to look at the use effect dependencies and if i put in an empty array here as a dependency this will only happen at load time so i'll put in here load time and let's save again and we already got load time here as it re-rendered as it showed the changes i'll go ahead and clear the console and just load the app again to show this and you can see we got load time so if i type letters now in the search box we don't get that count it doesn't continue to happen because that use effect only runs at load time so now we've seen examples of it running all the time for every render and we've seen an example of it running only at the app load time just the one time because this array never changes and this is a dependency and so what use effect does is it looks to its dependency and if the dependency changes then it will run this anonymous function again so now let's go ahead and look at something like the items and that is our state up here items so that's our item list specifically so not when we type a letter the state of the items doesn't change but when we add a new light item to the list or remove an item so let's put in the console log now updating items state and we'll save that and again we see i'll clear this console so we see only what we expect now and that is updating item state you get it once immediately when it loads so use effect does run and item state is set when the app loads so that is accurate but then any time we delete an item like removing pizza now we get another one here updating item state or if we add cookies we've updated the item state again so now use effect is only looking at its dependency and it's only running this function when the dependency changes now that we've discussed the different times use effect may run let's also discuss when it runs as far as in the order of rendering so i'm going to put a console log statement here and i'll put before use effect and i'll go ahead and copy this and i'll put one as you might guess after use effect and here i'm going to put one and say inside use effect now that we've got all three of those i'll save and i'll clear this out and reload again just so we only see that and look what we get we get before use effect and then we get after use effect and then finally we get inside use effect so let's discuss this as you might expect we got the before one first but you didn't expect to see the after one second probably you probably thought this would just go in order but this is not synchronous use effect is asynchronous in that regard and it actually runs the code in here after everything has rendered down here as well so if there was any change if there was a need to re-render such as me typing a letter into the search box now we got before and after again that re-rendered but use effect was not called in the action because we didn't change the state of the items at all so we'll only see this inside use effect when we change the state of the items but for every letter i type here every render we get another before and after now that we have a very clear idea of when use effect is called into action let's discuss how we can apply it to our application and right now i'm going to set it to run only at load time again and we can take this json parse where we're loading out of local storage and remove that and put it here inside of use effect but i'm going to put set items and there we'll put in the local storage so now at load time we'll set the items the state of our application to this shopping list that we have but we need to go ahead and initialize you state with an empty array as well let's go ahead and save this and now you can see our items are back i'll go ahead and remove the console log statements and this would be an ideal way to load this data in especially if we were working with an api but since we're working with this local storage i have another idea about what we might do with our application let's go ahead and remove the shopping list here and remember this is a big thing to remember you would never want to set the items inside of use effect if you had an item's dependency because this would essentially create an endless loop you would be updating the items and every time that items are updated use effect would be triggered and you would be setting the items and it would go in that round and round and round in that endless loop so you would not want that but right now let's put our loading data back in use state because this also works very well with local storage and i'm also going to put a short circuit operator in here and keep this empty array and we didn't have that before but we probably should have let me save this the use effect will be okay here for now and discuss this for just a moment because if we didn't have this let me remove it and save once again i'll clear this out reload the application and let's take instead of the console let's look at the application tab in dev tools and here's our shopping list and it's got three items if we remove these items we have an empty array and that's fine our application works and says your list is empty but if we had never ran this application before we wouldn't have this shopping list inside of our local storage either so the new user that would come to our application would not have this and now let's reload and see what happens we get an error because we're trying to filter a null value and this just simply isn't there to pull in to set the state with so it's set to null we need to put in that short circuit operator whoa i got rid of the whole thing we need to put in that short circuit operator and put in an empty array so if this is null basically if the shopping list doesn't exist the application will at least have an empty array to work with so now if i save that now we have an empty list here and that's what we would expect to have okay since we've had that discussion now let's talk about what we can do in our application since we can load the local storage right here let's go ahead and save the local storage inside of our use effect and this needs to be items because it will be the current state that we'll be saving to local storage now and any times items changes we will do that and so with that we've taken out half of our set and save items so now we just need the set items i'll copy that and now select all these calls to set and save items and we'll just change them to set items and we can completely remove this set and save items function and we should still get the same functionality that we've had so i'll save this now right now we have an empty value here for the shopping list so we can tell our short circuit operator worked we previously didn't have a shopping list so it pulled in this empty array and remember use effect runs once at the beginning so let me clear out the previous errors we had and i'll reload again use effect runs one time at the very beginning so it already went ahead and got that empty array value and it set it into local storage then immediately when the application loads from there everything should work as it did before bread chips milk and let's look at our list in our application tab and there's our shopping list with all the items if we delete the items it's still empty and that should work and even if we delete the shopping list out of here completely and we reload now we get an empty shopping list and that's what we want so we've really made our application a little more efficient by using this instead of loading everything at the beginning we're looking at the state of the items and then saving our local storage to be pulled back into action next time okay we've learned a lot about use effect today there are a few more features that are a little more advanced that we could cover in a future tutorial right now we're going to move forward with this project and in the next tutorial we'll be setting up json server to mock our back end for our data api and then we'll come back and use use effect to load data instead of saving to local storage today we're looking at json server it will allow you to quickly launch a development api that you can work with as you build your front-end applications i'm at npmjs.com and here we can search for [Music] json-server i'll press enter and you see it is the first result and when i click that we get the documentation for json server but one thing i want to point out it says to install use npm i json server we're not going to do that we're going to use npx because we don't want to add json server as a dependency in our react application we just want to launch it and work with it and mpx will allow us to do that instead of installing with npm let's bring up visual studio code and get started here we go i have got our grocery list react application open that we've been working on throughout the series i'm on the app.js file but that doesn't matter so much right now in fact i'm going to bring the source folder back up here so we don't see all the files i'm going to create a new folder and i don't want it in the source folder i just want it in the file tree i'm going to just call this folder data and then inside the data folder i'm going to create a new file named db.json as you might expect this file will hold all of the json data that we will use for the back end and i'm just going to paste in some starter data here that we would see for our grocery items list now notice some differences compared to when we hard coded in items when we initially started the project and the main difference to notice is all of the keys are in quotes that was not the case when we put the json right in our javascript and then of course between each json object here is a comma so let's look at the data then an integer does not need to be in quotes a boolean is not in quotes but the string that we're using for each item is in quotes so make sure you have that correct and then also it is nested here this is an array and it's the items array and then there's the objects inside of the items array and items is also inside of quotes and overall this is a full json object now i'm going to put this source code in github and link to it in the description below so you could also just copy this out of the github source code if you go to that link all right i'm going to save this file and i'm going to open a terminal window and we would want to use a different terminal window than we run our react application in and you can easily do that by pressing the plus over here beside where you see the word bash and you can start another terminal window so i haven't launched the react application but i would do that in a separate terminal window as well here i'm going to type npx not npm but npx and then i'll type json server and then dash p and that stands for port and i'm going to put 3500 and then i'm going to put dash w which stands for watch and then type data slash db dot json and it will take it just a minute but the server will launch and now the server has launched and we can see some messages here i'm going to expand the terminal window and scroll just a little bit it's giving us some addresses for the resources already so we can see it's running at port 3500 on localhost and to get our data we would go to the items path so i'll just go ahead and copy this and i'm going to resize the window here and then pull up just a blank chrome window and i'll type this address right into chrome and press enter and now we get our json right here inside the browser i'm going to go ahead and resize chrome as well and so we can see both things here in the window i'll pull this one down there we go pull this over and let's take a look when a request comes in now here in the terminal we see it was a get request and it requested items the response code was 200 and it even gives us the milliseconds it took to return that request so let's go ahead and refresh and we should see another get there i had to scroll the window just a little but another get request came in for items let's do it again looks like there's a little bug right now where i'm having to scroll the window to see the next request come in let's try it a little smaller and hit there we go now we're just seeing it without me scrolling but each time we request that resource we can see it logged to the window where we have json server launched and that's really almost all there is to the json server that we will need for our project i'm going to open another bash window like i talked about and here i'll just paste in that resource again now this is the address that we will request all items from and that would be a get request but we could also send a post request to this same address here at the slash items to post a new item but when we want to update an item we're going to include a slash and whatever the id is say if it was post number one we would have the number one there and likewise when we delete we would also have the id because we would want to delete that now those are different types of requests also so you could have a get request a post request when we update an item we're actually going to send a patch request and then a delete item is called a delete request okay we're going to take all of this and move forward in the project in the next tutorial we'll be working once again with use effect but then also with async fetch requests to do these exact crud operations that is create read update and delete in the last tutorial we learned about using json server to run a local rest api as a development server where we could work with it and use that rest api as we develop our front end and that's what we're going to use today as well so you can see i've got visual studio code here on the left and on the right i've got chrome open i've got the grocery list application we've been building in the top right i've already got dev tools open the console is available here on the bottom and i've also opened a bash window here at the bottom of visual studio code in the terminal and this is the window i'm running react in of course with npm start now we need to open another terminal window to go ahead and start the json server and if you remember from the last tutorial instead of npm we use npx and then we say json-server and then dash p for port and i'll say 3500 w for watch and then we say data slash db dot json and that is because we have a data folder and in here we have our db.json and i'm going to give a link to the source code for this tutorial that will be on github so if you don't have this json already the starter information you can easily get it from the link to the repository in the description okay i'm going to click on the app file so this is where we're going to do the work today but i need to press enter down here to start the json server and when that finishes we will be ready to go it'll take just about a minute and i'll be right back okay with json server now running i'm going to click the little up arrow here just beside the x in visual studio code to expand the terminal window and scroll just a little so we can see some information it gives us resources it's running a local host with the port 3500 as we specified and then we're getting our items so this will be our root url that we will contact with the fetch api to get information so i'm just going to copy that and then i'll go ahead and click the down arrow and then we can just x out of the terminals they'll continue to run the server and react for us and we can display those again if we want to but now just under the function app here for our app component i want to put a const and put the api underscore url and i use all caps for that because this will be a constant in the true sense of the word where this url will not change for us so we can refer to it as we create the different fetch requests and i'll put one line after that and go ahead and save the file and after that we can look at our use effect and let me go ahead and press ctrl b as in boy to hide the file tree and then i'm also going to press alt z so it wraps some lines of code like you see here on line 11 where this line of code would be longer and it just wraps it down and then line 11 takes a little more space again that's alt z as in zebra okay now that we've got that going i'm going to look at use effect here and also this used because we're loading our current data from the local storage as we had in previous tutorials and for some reason if we didn't have a shopping list like say the reason would be we hadn't ever accessed this application or a brand new user we at least need to load an empty array so we don't get errors by trying to access properties of the array from our code so instead of getting this data from local storage now we want to just go ahead and remove this loading part and the short circuit or operators but leave the empty array for the use state and that's the state we want to initially load the application with and then we will switch down here to the use effect and where we're saving these items and listing for any changes in state in the use effect dependency to items we can get rid of all of that as well because we're going to use effect with an empty array as a dependency which means what happens in use effect will only occur at load time because we only want it to happen that one time and that's when we would load the data from the rest api and after that we can manage it in state but then we will send messages back to the rest api to keep that database in sync with our current state of the application now because we want to use async await it's important to note that we cannot do this with use effect async won't work that way with use effect and so you will often see the old way of using fetch inside of use effect and that will chain venables as you would use fetch and put in the url and then have a then afterwards and possibly another then and so on we're not going to do that we want to use async a weight and so we need to just define an async function that we can call inside of use effect now we could define that function outside of use effect and then call it in if we wanted to use that function elsewhere as well because then it would make it available to the rest of the application we're not going to though because we only need this function inside of this one use effect call at load time so i'm going to define fetch items and make this an arrow function and of course we need to put async right here and now that we have determined that fetch items is an async arrow function we'll start with a try block and then of course you want to end a try block with a catch block and we would catch any error and so in the try block we want to put our fetch statement and we'll define a response that we expect to get and we will await a fetch call and here we will just need to fetch the api url and this full url right here if you were to paste this inside of chrome it would of course perform a get request by default and it will return those items inside of our db.json and those are running from the rest server the json server so we get this response and after we get a response what we would typically do is say okay these are wait a minute lowercase here these are our list items that we want and here we'll await the response to convert to json just call the json method and there we would have our list items and then we can set our items to the list items and that is typically what we would do to get the information now we need to think about the error as well we would get an error here so for now let's put a console log and just put the error that we would get or let's do the error stack so we get the information let's go ahead and log this information to the console as well up here just to make sure we're getting these list items from the json server we're going to modify this fetch just a little bit as well but right now i just want to start with this information so let's go ahead with this but look we're not calling it yet so how do we call this async function inside of use effect well what we need to do is of course being an async function it kind of needs to be called in its own async so we're going to put in an instantly instantiated async and here we can call fetch items and await the response and so we'll say await fetch items and then we need i believe no we've got the two parentheses there so then we just need at the end the operators to call it into action and after that we'll go ahead and save and see what we get okay so we still loaded our items because we set the list items and also it logged the list items to the console as we see right here i'll ex bring this up just a little to have some more room and we can see the list items right here so this worked as we expected it to now we're not updating anything yet at the rest api so if i change the state of the application here such as checking bread we don't see that changed here check did not turn into true this just loads at load time because this is in use effect and it's an empty array so it just happens the one time we're not going to see this reload in the console and have console changes here it only happens the one time so if there is another change in the state of the application a re-render we still won't see this operation happen again because once again this use effect operation will only happen at load time now let's go ahead and cause an error and see if we get that back in the error right here as we would log it to the console so i'm going to go up to this url and i'm just going to put an extra s here so it will not find the url and let's go ahead and save and we should reload the application and we've got an error in the application because it says items.filter is not a function and so we didn't really catch the error here at all in fact it actually produced an empty list or a null list if you will and then we set this to empty essentially null and then we couldn't use the filter on items like we have in jsx it's it's trying to call an operation on something that doesn't exist and that is the error so if we look back up here get past all this error code i can bring this up a little more way back to where we were you can see we got a 404 not found response and that wasn't logged here as we would see on line 24. it's actually an error that comes from the response we did get a response and then line 21 went ahead and executed here and we logged the list items which was just empty and it's not an empty array so we actually need to do something to catch this type of error as well what we're going to do is set up a fetch error with state and so i'll define say const and then here i'll say fetch error and then of course set fetch error and we'll use state with this so we'll say use state and we'll just set it to null to start out i guess it wasn't using semicolons after all that i've been a little inconsistent let me go ahead and add the semicolons here just so i can stay a little more consistent okay so we've got fetch air and set fetch error and now what we need to do is after we get this response and before we set it to list items we need to look for an error so we can say if response okay but what we really want to do say is if the response is not okay now our dot okay is equal to a 200 response or a response in the 200 range which would indicate an http status of okay and then if it's not okay that means we got something like a 404 as the response and so now we're going to throw an error and i'm just going to say did not receive expected data as the error message and then that would come down to this catch block so then we would actually see this error caught and let me go ahead and clear the console and then i'm going to save this and we'll leave this extra s in items so we still get the 404 error but let's see what happens now we don't get that huge list of errors in the console what we do get is the 404 but then we catch the error and the error is put here did not receive expected data so that works to catch our error in the fetch and instead of the stack now let's just log the message property here i'll save and it should do it again and now we get did not receive expected data instead of error did not receive expected data so it just made it a little bit smaller a message overall of course it's warning us that fetch error and set fetch error have not been used yet and that's what we need to do is handle this error so we're going to set the fetch error here if we've had a successful request after we list the items and we will set it to null because previously we might have had a fetch error set that was not null so we want to make sure that we're setting it back to null here and then as we catch this error we don't just want to log to the console we want to set the fetch error and here we'll set it equal to the error message and then we can go ahead and get rid of this console log because we have got the fetch error saved in state and then after that we should save now we won't see this logged here now but we do see the 404 error in the console anyway but let's use this fetch error in our jsx to indicate to the user there has been an error and we can deliver a message based on that so down here in our components here's the return with all of the jsx our content if you remember really contains the main element and then the list items that go within the main element so what we can do is before the content we'll put the main element here and then i'm going to just take the closing main element and put it under the content and then highlight the content and tab over we'll save that it hasn't really used fetch yet but or the fetch area yet but we will in just a moment i'm going to press ctrl b to show the file tree go to the content.js component for just a moment and instead of having the main element here i just put it into the app jsx we'll just make this what they call a fragment so in react you can have a fragment and here it doesn't have an element inside it but you need to have whatever you put in the jsx inside of a parent element or an element container and you can use a fragment to do that so it has a closing slash inside the less than and greater than and then just the less than and greater than with nothing in it is considered to be a fragment so we can save it like that and continue to keep the main element right here in the app component jsx okay now that we've made that change i'm going to press ctrl b to hide the file tree again and we can use the fetch error right above the content now and so i'm going to put the curly braces to indicate this is an expression and we'll say fetch air and that means okay we have an error now and then i'm going to put two ands the ampersand and so if we have a fetch error we're going to and now i'm going to put a paragraph here simple paragraph that we'll have in the main element and we will say error inside of curly braces with a template literal i'll say air and now we'll put in the fetch error and close that now we'll use the back tick to close the template literal then we'll have another curly brace because we're inside of the paragraph here okay now that we've got that expression let's go ahead and add just a little bit of style to this paragraph as well so i'll put in style equals curly brace now remember this is indicating an expression we need another curly brace and now we can put in the actual css properties and i'll put color and then red in quotations i'm going to press alt z to wrap as this got just a little bit longer wait a minute it's not wrapping there it is maybe it was already wrapping so the closing paragraph is right down here but we're just switching the color to red and i'll save that and now we can see our error displayed up here air did not received expected data oh i've got a typo there that is not correct i just want to say did not receive expected data let's save that now that looks correct did not receive expected data back in the jsx we can also prevent this your list is empty or if the list was not empty and we still had some error that would display we can prevent that from showing and we can do the same kind of thing we did here with this error message but in front of the content we'll put a curly brace and i'll say if no fetch error and we indicate that with the exclamation mark once again two ampersands and then we'll have the content but then of course we need to put a closing curly brace at the end of the content and now only if there is no fetch error if fetch error state is false then it will display this content component so if we save now the year list is empty message disappeared likewise we can come up here and fix our url and save and now we get our list items and of course they were logged to the console again as well so we have no error the error message did not display but the content component did okay our fetch request is working and we are catching errors including response errors that wouldn't normally be caught by the catch error block here in our try catch block however there's one thing still missing and we need to realize that an api may not be as fast as a rest api that we're running in a local environment like we are with json server so let's kind of simulate that by using a set timeout here in our code so i'll start the timeout and then it has an anonymous function and inside this function we can put our async call to fetch items and we'll make this wait two seconds before it makes the async call now i'll save this and let's reload the application now it says our list is empty and then we get the items so what we want to do is not have a false message saying our list is empty when it's really not we really want to tell the user the list is loading or that we're loading the data or some message like that when we're waiting on the api to finish that initial call so we're going to use one more piece of state and we'll do that up here at the top and we'll define const and here we can say is loading and then of course set is loading and after that we'll set it equal to use state and this will be a boolean either true or false and when the app first loads first render it will be true because we plan on loading that data so we don't really need to set it down here we're not reusing this function at any other time anyway so this is just based on the loading state we'll set it to true but then after everything completes we can with with a try catch block we can use a finally at the end and here we will set is loading to false and now we can save this and we won't see a change yet because we're not using it in our jsx but we are tracking the state of loading and we do not set it to false until everything is completed in this finally whether we've received an error or the fetch is completed as we want it to so now in our jsx let's go ahead and utilize this loading state as well once again inside the main element that we've provided we can put a curly brace we can say if we have i put loading is loading so if is loading is true then let's go ahead and show this and this is just a simple paragraph and we'll say loading items and that's really all we need we're just going to show loading items if is loading is true but we don't have to worry about our error block this will not show unless we have an error so we'll leave that as is but here with the content if fetch error does not exist we've been showing the content component but also we want if is loading is false and now the content component will only show if there is no error and if we are not loading so this is what we want so i'll save this so let's go ahead and reload the application now we get loading items and then the items appear so just in that brief time that we're waiting on the items during the load in use effect and again we simulated that loading time with our timeout here you do not want this in your code this is just a simulation but you can do it just for now to simulate that loading time and again that's slower than you would even expect from a server but it allows us to see it we hit reload we're loading the items and then they show up let's go ahead and remove the console statement out of the try block as well and there we have the completed async function of fetch items and it is only created and called the first time the app loads in use effect and the other benefit since we're not sharing this function elsewhere in the application of having this defined inside use effect is this function is not recreated or redefined every time the component renders it's only created this first time and called into action in the last tutorial we put a fetch items function using async await and the fetch api inside of the use effect hook in our app component and this functional app component is the parent component for the rest of the components in our application and here we are also simulating a call to an api using a two second timeout but we're really running a local json server instance and we're accessing the data from our db.json file so if you didn't see that tutorial hit that playlist link in the description below and go back to it for that setup i'm going to pick up right where we left off because we're requesting the data from the api and that goes ahead and loads it in here and we've got our console list items i need to remove here once again i'll do that and save and so there's the completed fetch items function that is called inside of the use effect and since we've completed that we need to go ahead and link up the rest of the crud operations and those would be this is read as far as crud goes we're reading the data but these other operations would be create for creating a list item update for updating a list item and delete for deleting a list item so let's go ahead and put those in place as well so now instead of being in the app component i'm going to press ctrl b as in boy to show the file tree here in vs code and i want to add a file and i'll click the new file icon i'm going to type api and then a capital r and spell the word request.js so this is api request and here i'm going to create a function that we can import to use for all of these other operations so we'll be abstracting some and this will allow us to use this one function for create update and delete we'll start out with a const and we'll call this api request and it's going to be an async function and it's going to accept a url we'll put in a default parameter that is just an empty string and then it's going to accept an options object i'm going to press ctrl b once again to hide the file tree now and this will be set to null as default to start out and it's also going to have an error message and this is also going to be set to null to start out from there we'll put in the arrow for our arrow function and now we'll be able to define our function but we also need to remember to export this function so at the bottom just like we do with a component we can put export default and put api request okay with that setup out of the way let's go ahead and start with a try block as we would with any request and the setup inside would also have a catch for an error and then it's going to have finally at the end that happens whether we've had an error or not this will always execute after the try and catch blocks so now that we have our three blocks let's define our generic request and this will be defining a response that we expect to receive and we'll set that equal to await fetch and we'll use the url and fetch also accepts an options object and that's what we'll have which is the second parameter that we have here for our api request function as well so we'll accept both of those and really the options object is what makes the difference between this being a create update or delete request after that we'll check to see if the response is okay or not and this is a lot like our fetch function that is back in the use effect of the app component and this is saying if we do not have an okay response if it's not in the 200 range maybe we had a 404 we want to catch that and throw an error because we know that will not be automatically caught as an error it's just a response that we didn't want and here we'll put please reload the app and of course in our message that is shown up in our display when we get an error it will also say error but we already have that coded in so here we'll just say please reload the app and that's because at this point the state of the application may not be in sync with the database if we've had an error with creating updating or deleting they'd be out of sync we reload we'll get that data back from the server once again and our state will be updated to be in sync with the server so that's why i've got a please reload message after that let's go ahead and define the error message in the catch block and we'll set the error message equal to error dot message and then in the finally block this is where we actually want to return the error message so no matter what this return will happen whether the error message is null or whether it actually has a value and we don't really need the responses back from the api here we'll go ahead and put a semicolon there as well and the reason we don't need those responses back is because we're updating the state with our set items and other set functions that we would call from our state however that does not update the api and we want to keep the state of our application and the api in sync but we can update the state and see that faster than we may get a response from the api so we don't want to wait for that response we'll just instantly show the new state in the application but then if we get an error message we'll know we're out of sync with the api and then we'll show the please reload the app message here or whatever other error might actually occur that would be caught by the catch block here we can show that message as well so this is our function that's really all there is to it and the difference between the requests will be the create update or delete that is held in the options object and we'll define those in the separate handlers so let's save this api request now let's go back to the app component now in the app component let's go ahead and import this function will import api request from api request and now let's put this api request function to work and the first place we could use it is in the add item function we've already got everything we need here to update our state and we do it right here with the set items but besides that we want to go ahead and update the rest api as well so here let's define the post options because this will be a post request and i'll set that equal to an object and we'll define the method and that will be post and after the method will define headers now headers is an object all of its own oh we need lowercase there we go headers and so this is an object and inside the headers we'll define the content dash type and this will be application slash json and then we can put a comma after that headers object and we need to define the body and for the body the information we want to send we need to send we need to use json stringify and here we can pass in my new item as we defined above again we don't need to send oops we don't need that semicolon we don't need to send the full list of items like we set the items here in our state we just need the new item that we want to post to the rest api and that was defined by my new item up here above and with that we've completed our post options so now let's go ahead and define the rest and send the request so we want to say const result equals oh and this is a weight and remember our api request was an async function so we need to change our add item to an async function up here above and that way we can await the api request and we can pass in the api url that we defined at the top and if you remember that was a constant and here it is as we just open the app component function and for a post request we don't need to do anything other than send it to the same api url that we send the get request but the method being different will handle the request differently and this is a post request so we're just sending it to the full api url again and not changing that url at all and then we need to put pass in the post options so the url and the options that we've defined and if you remember and let's look at our api request all it returns is the error message that's all this function returns either it's null or it's not and we have some type of message that we've received this error.message for example so if we look back here we can just check now in what we've received as our result and we can say if we have a result that means the message is not null then we need to set the fetch error and of course when that is not null it will actually display in our jsx as we've set that up previously so let's go ahead and save that and after that save i want to display the terminal so we can actually see json server at work and we can scroll this up and then scroll down and here's all the get requests that have happened and these are 304s by the way if you notice that now i mentioned a response that is considered to be okay in the 200 range so why is a 304 okay and if i reload i bet we get a 304 again there it is yes a 304 at the bottom and that means it's using cached information it means it doesn't really need to get that information from the server because nothing has changed now a 404 is definitely an error and a 200 doesn't show right here at the beginning i guess we too far past that a 200 range response means okay but there's nothing wrong with the 304 and we will not catch that as an error either so we can reload we get the 304 here that's fine but what if we post an item let's see what response we get so we'll add an item let's add cookies and click the plus we've got cookies and it was a 201 which is in the okay range and look it was a post request now and so that works as we expected it to i'm going to close the terminal window again but i'll press ctrl b and let's go ahead and open our data folder on the left with json server and if we click the db.json and look now we've got cookies added to our json file as well so it did update the file as we expected and it did handle the request as we expected now let's go back to the app component and we'll handle the check now let's go ahead and define that once again we already have the code here that updates our state so we'll just enter in something new below that i'm going to press ctrl b once again to hide the file tree but now we can define the item that is getting updated as right now we just handled the list items and then we updated the full state of the list items and we essentially just changed the check for the item that was checked but we'll need to handle this just a little bit differently here we need to get the item that is checked so we're going to say const and i'll just call this my item and now we can use list items because we've already updated the list items and now the checked is in the state that it needs to be essentially so here we can use list items and we'll say list items and we'll once again use filter and we'll just have the item here and use the arrow and then say the item dot id and this needs to be equal to the id that was passed in and so if we do that we will now have defined my item and i'm just now noticing i've got item in parentheses here in a couple of spots with filter and then or even map and then i have item not in parentheses so just to be consistent i'll go ahead and put this in parentheses but it's not really required you wouldn't have to have those i'm just adding it for consistency okay now define update options because we are going to update and not we're not posting this time but update is the word from crud really the method we'll use is called patch so we're going to set this equal to an object and here we'll define the method and this will be patch as we're updating just a specific part of a specific record and now once again in the headers this will be just like before this is content dash type and this will equal application slash json now that we've defined the header we'll move down and define the body and here we once again you need to use json stringify and we can pass in a specific bit of json here and we're going to say checked so just the checked property of this specific item that we're sending with a patch method and we're going to say my item but remember now the filter returns an array so we have to say my item zero it's an array with one item and we're referring to it this way my item zero dot checked so whatever the check property is we're not changing the checked property because it was already updated before we accessed the list items here and that will handle that sending the correct information now that we've defined that object underneath we need to define the request url because this is just a little different than just the url that we used for git and post this will be equal to a template literal and we'll start out with that api url but after that we need a slash and then we need to use not a space but we need to use whatever id was passed in so if this was post number one it would have the id of one right here so we're accessing a specific post that we're updating with patch and now we can define our result again we can set this equal to an await call which means we need to change this handle check to an async function as well here we'll say await and now we'll put api request we'll pass in the request url and we'll pass in the update options and now once again the api request will only return the error message and that error message is either null or it has a value so we can just say if we have a result we know that there is a message that is not null so we'll set the fetch error and we'll pass in result and we can save that and now if we check an item and we should see it i'll once again open the terminal so we can see what the request is here and i will check cookies and we see the patch request came in and it was items but also item with an id of four and then it updated the rest api so we have cookies checked and we could uncheck it and we'll also see a request come in and it will once again update that now let's go ahead and close the terminal and we'll look at the db.json once again we've got cookies here let's check cookies and it changes to true right inside our file it's updated just like that by the json server and if we uncheck it should go back to false that's exactly what we expect for the update okay we have created an item we've updated an item so really all that is left is to delete an item because we were reading the items from the previous tutorial to begin with and that happens right at app load with the fetch so let's go ahead and update the handle delete and here you can see we're already updating the state once again so let's just put a little space here so we are defining what we need to update the api that's just a little bit different than updating the state but of course we're trying to keep those in sync as well and if we get an error of course reloading the app will put everything back in sync so we've got delete options that we're going to define and that's very simple for a delete we'll just set the method equal to delete and it really doesn't get much simpler for the options than that and after that we could have our request url that we need to define which is just like above so we can really copy the request url because it's also the id that's passed in which reminds me we need to change this to async as well and let's go ahead and do that with lowercase and then the result is going to be very similar here so let's copy these other two lines and paste underneath but instead of the update options this needs to be delete options other than that the function operates in the same way so if we get a result back we want to set that fetch error and if not we know there is no error to set so we can save this as well now let's once again open up a terminal i'm pressing control and backtick to open that up quickly there we've got the items and once again it was a 304 we didn't need it after we had the 200 with the items because everything was fresh um the get request with the 200 is what loads them in here so now let's go ahead and delete cookies and see what we get in the terminal too we deleted cookies and now it was our delete request and once again we got a 200 response everything was good and that was item four so we can check pizza we got a patch request let's uncheck pizza another patch request because that continues to update it we can add an item let's go ahead and add something new here let's get some candy add that in that's a post request everything is as we expect it to be and once again if we delete candy we get a delete request so our crud operations are complete if we reload the full app we should get the get request or at least yes we've got get with the 200 there so everything was as we expected to be our create read update and delete options all of our crud operations are functioning and we have eliminated using local storage in today's tutorial we're starting the second challenge of the series now that we've learned about use effect and fetching data with the fetch api now we're going to go to this website jsonplaceholder dot and we'll use the resources from this free fake api to request these resources of course with fetch if i scroll down we can see the resources listed here we're going to use comments and users now if we click on one of the resources it will give us the full link which is just based on the root url of the website and then slash posts comments or users but you can see all the json data right here in the browser by doing so hit the back button and come back to this site but again you'll need jsonplaceholder.typeycode.com for these resources and you'll want to remember those resource links from there let's look at the challenge now this is a two-part challenge so i'm going to introduce part a now and i'll introduce part b later in the tutorial so right now as we build out part a we want to look at this result and we have three buttons at the top and you can see i have user selected when i select users it requests the associated resource from the json placeholder website and then it prints a list of all of the objects we get back and notice these are the full objects that we get in json format here and each one is a list you can tell by the bullet points it's just an unordered list on the page but if i click posts the whole presentation changes and now we're displaying the posts likewise if i click comments we're now displaying a list of all of the comments received and so that is part a of the challenge create this same application that provides these different resources on the page at the different button clicks now i'm going to give a couple of hints for this part a so if you want to complete this without the hints go ahead and pause the video now and work on the completion and of course after the hints i will start to show the solution okay hints for part a if you don't want to hear these make sure you have paused the video part a requires you to print a list of each of the objects you receive all these json objects and of course you're going to use use effect and anytime one of these resources changes users posts or comments you will want to run what's in use effect so the dependency for use effect should be the request resource or as you change part of that request so users posts or comments would be changing and then use effect could run the same fetch to request either one or any one of these resources so that should help you also remember as you display objects in the web page you'll need to use json stringify you can't just display javascript objects you need to stringify those objects so that could also be a little hiccup if you weren't aware of that so use json.stringify and then you can display the objects so with those hints go ahead and pause this and complete the challenge to the best of your ability and then i will go over the solution before introducing part b of this challenge okay to start the challenge i've got visual studio code open i am in my react series folder that has all of the tutorial folders here so i want to be in a parent folder is what i am saying and then i am using npx and i'm going to type create dash react dash app and then i'm going to type 15 tut you can name your folder for your project whatever you want to but that's what i'll name it i'll press enter and start the create react app process this will take a little while so i'll come back when this completes okay create react app has finished we have our happy hacking message and now remember we're still in the parent folder so we need to go to the file menu and then open folder and from there we should be able to choose we've got react series and then i'm choosing my 15 tut whatever you named your folder and let's open that in visual studio code okay we have our new project folder open i've got visual studio code on the left i've got chrome on the right and i have the json placeholder site here for reference let's go ahead and do a little cleanup here at the beginning of the project in the source folder i'm going to select the app.css the app.test.js the logo the report web vitals and the set up test dot js and i'm going to press delete just to get rid of those files after that in the index js i'm going to select everything at this bottom of the file here where it has the comments and report web vitals just hit backspace to get rid of that i'm also going to remove the import for web vitals now i'll save the index.js file and in the app.js i'm going to remove both imports at the top of the logo and the app.css we don't have those files any longer i'm also going to select everything between the div that has the class name of app and just hit backspace to delete that so we've basically cleared out our app.js and now we're ready to begin building our own project at the top of the app.js i'm going to import a couple of hooks that we're going to use so i'll import use state and use effect and these will both be from react after that we can come into the app function and i'm going to define the api url so i'll have const and then api underscore url and i'm going to point that at the web address that we get from json type holder so i can just jsonplaceholder excuse me so i can just paste that in from the web i'm going to press ctrl b right now to hide the file tree and now we can see the full code and i don't need to add the resource after that because that's something we're going to change so this will work right now but remember as we change the resources this will say posts users or comments after this address so right now we just have that now let's think about the state we're going to use because we're going to change the resource type or we could call it the request type and that's what i'm going to do so i'll say constable i need lowercase and then i'm going to say req for request and then type in camel case and then of course set request type and from there we'll set use state and i'll set the first type to users it's going to be one of three it could be users posts or comments you could do any one of those three i'm going to start with users from there we need to think about what we get in return so we'll get some data or we could call each piece of data that we get items and that's what we did previously in a project so let's go with items we'll just say cost we'll have items and set items and this will be the data that we get back so really our objects that we get but it will be an array and it would be a json array so we get the array that has the json objects within it and there's our state really that's all we need so we can save that much and while we haven't worked on the display yet we can go ahead and just create some logic because we've done this before we know what we're doing here we've just got use effect and it has an anonymous function and inside this anonymous function we can then specify a dependency at the end this of course an empty array would just make it happen at load time but that's not what we want we want this use effect to take place any time the request type state changes because it's going to be one of three things users comments or posts so this is our use effect and it will actually run every time our request type changes so now we need to put our fetch items function inside of the use effect and then of course call that function so we'll start with a definition of fetch items and oh this needs to be async there we go and we'll make it an arrow function now inside the fetch items function i'm not going to get as detailed at least in this solution as i did in a previous project tutorial where we build out our list but we'll get the basics here so we're getting a response we're going to await a fetch call and the fetch call will be to the api url but remember we need to add a little bit to that oh and i'm showing the errors because i didn't put an equal sign there we go and now we need the api url in a template literal and this will allow us to add a little more to this api url at the end because remember we need to change the resource now we have the slash already up here in the api url so we don't need to put a slash here but what we do need to put is the request type whether it's users comments or posts so we put those two together and we get the fetch url that we need after that let's just define data and we'll set that equal to we need to once again await the date or response dot json i almost said data there but we've got the response we change it to json and then there is our data and then we can just set our items equal to the data now i'm not putting in the line where we would check to see if the response is okay or not or create a separate error and handle those but if you did that in your solution that's great that's just going the extra step here for a challenge project what i'm going to do for any errors that we would get that wouldn't be fetch or returned in fetch is just to say error and of course we know in a serious project we should check to see if the response is okay log and error and not set the items as we've seen in the previous tutorials but this is the basic fetch here with the try catch block and now all we need to do at the bottom is called fetch items again this isn't returning anything we don't have a return for data so we don't really need to await this fetch here if we did we could use an instantly invoked function and await the return of this fetch but that's not needed so just put the semicolon after that call and save and we've really completed our use effect that will fetch these different resources as they change and now we've essentially handled the logic here in our function for the app component so we need to think about the display and what do we want to display here well we're going to have and i we could do comments or we'll just discuss because it's very small we'll just have two components that come in here so we'll have a form component and in the form component we're going to pass the request type so we can specify that now and after the request type we're also going to pass the set request type and so we'll go ahead and specify that now as well there we go and then we can just close out the form and then after that we'll also have a list but let's work on the form for now so i'm going to go ahead and expand visual studio code to take up the full window for just a minute and then ctrl b is in boy to show the rest of the file tree and now we'll just create that form component and here i'll type form dot js and now using the snippets that we've installed the extension for react i can press ctrl alt and the letter r and then it's underscore r a f c e now this is a shortcut it's not necessary you could just type out the code for this functional component here as you see for form it's just generic code and it's an arrow function now our form is going to receive those two props that we were passing down so it was request type and i'm destructuring up here instead of specifying props and then using dot props so i've got request type and set request type and then in the return instead of a div we're going to have a form and for this form oh and i use capitals that's why it's green what we really need is lower case so i'm going to select both of these and say form there it recognizes it as an html element so again use lower case my bad there but we'll have an on submit and have this equal to an anonymous function that has the event and here we'll just say e dot prevent default because we do not want the default submit that reloads the page every time a button is clicked so that easily eliminates that possibility now our form is going to contain buttons but we haven't really created those yet so let's save this and we didn't save our app over here because we had the form but we hadn't imported it so at the top of our app.js let's import form from dot form there we go and we can save that and now if we look back at the form once again this is where we need to put our buttons so without putting those in here let's just go ahead and create a button component that will be reusable because we're going to have three buttons and we'll do the same thing here ctrl alt and the letter r now underscore r a f c e and now we have a functional button component let's just go ahead and save the empty button component as is for now and import it into the form because that's what we'll need over here at the top so i'll say import button and we can just click on that and it completes the import and from there let's put our three buttons in the form so button and now i'll just use shift alt and the down arrow to copy that down a couple of more times so now we have three buttons let's think about what props go down to the button i'm going to go ahead and click inside the button and put the props on separate lines well the first thing we could do is set the button text here much like we would a title and we'll be able to use that in the future so let's set the button text and we'll set that equal to users and after that we could go ahead and do the request type equals request type and pass that on through and then we can do the same with set request type and have that equal set request type so those are the three things we need to pass to each button i'm going to go ahead and copy this let's see actually if we can select the whole thing and now i can use shift alt and the arrow there we go and i'll just eliminate those earlier buttons we created but we need to change we don't want three users buttons so we've got users and let's go with posts and finally we'll go with comments as the button text so now we're passing in the three different props that each button needs and we can go back to the button js and complete that so let's destructure those props and this will be button text and then it would be request type and then it's set request type now in our button itself we don't want to div we actually want a button element and so this makes sense to go ahead and change those to button and now on separate lines we can once again work with the different attributes for a button element we'll say class name and let's set that equal to and here this isn't what you expect we wouldn't just put a class name and say button we're going to decide what class it is based on that button text prop so we'll use the button text we'll say if it equals the request type so if the request type equals users and the button text is users then we'll use a ternary and say if this is true we're going to give it a class name of selected otherwise we'll just say null in other words no class name and that will help us as we apply the css to show which button is actually selected from there we can say type and here's simply button we don't want a submit type we want a button type and then for the click on the button the on click event here we'll put an anonymous function and with this anonymous function we'll set the request type and the request type will be the button text because that's what we've passed so if it's the users button we'll set the request type to users if it is the post button we'll set the request type to post and that continues to make sense for all three buttons from there we know we need to put some text on the button which is just the button text itself here between the opening and closing tags and we can save our component so we've completed our button component that's reusable and we use it three times in the form component and then the form component is imported into the app component and we see it will be displayed here so with this much created and again it's just the form with three buttons but let's go ahead and open a terminal window i do that with control and the back tick button but you could go to the terminal menu and do it that way as well and now we've done that let's go ahead and start up the dev version of our application by typing npm start and pressing enter this will take just a moment but should launch the application and with the application launched you can now see the three buttons that we have at the very top of the web page and so far that's what it is it's an application with a form and three buttons i'm going to go ahead and select visual studio code and resize it so it kind of is to the left and chrome is to the right but we're started and now that as we work on our application we'll continue to see the changes over here i'm going to go ahead and close the terminal window it will continue to run our application i'm going to quickly select the index.css again this is focused on react and not css but i'm going to just replace what is currently in the index css with mine and of course i will have this css in the repository at github that i'll link to in the description below so you can copy this over if you want to but this is just to make the tutorial look a little bit better and i'm not going to focus on it and it's really pretty short here let me look like less than 60 lines of css but overall you can use that from the github repository link below in the description now let's go back to the app in the app i'm going to scroll up here just a little bit and before we set the data or set the items in the fetch items function i'm going to go ahead and log the data before it is set as an item and i'll save this and then i'm also going to right click on chrome and inspect and i think i've still got my console down here at the bottom yes let me check and choose console and yes we got an array let me do that one more time and there we go an array of 10 items it's giving me a warning because it says items is not used at this point in the application but we are logging the data here and so it is working we're getting all the users from json placeholder now let's work on displaying that data and of course that will eliminate this warning about items because we'll start using the items in our application so if we scroll down all we're going to need below the form component is a list component and here we'll just pass the items and that little piece of state which is all of our data we'll pass that along to the list and now we need to create the list if i save right now we'll get an error so i'm just going to go over here to the file tree create a new file list js and now in this list js again control alt and the letter r and it'll be underscore r a f c e there's our functional list component i can just save this much and now i can probably go back to the app.js and save it without getting an error well no we haven't imported it yet so we got the error anyway import list and i can click on list and it's imported from dot slash list and now will we have an error probably not let me clear it out and reload once again yes everything is good now we're still logging the data to the console for now too so we could go ahead and remove that i don't want to leave that console log statement in there save that and clear out the console reload yes no data is now showing everything is as expected so now we can go create our list i'll click on the list file here and i'm going to press ctrl b once again to hide the file tree now inside the list we're going to return an unordered list and we're receiving [Music] the items prop so i destructure that right here and we want to map through the items that we've received so would be items.map and here we'll get an individual item and have an arrow now this is a parenthesis not a curly brace and we can have a line here and now we're going to use another reusable component and this will be a list item so i'll have list item and list item will need a key because each item in a list as you map through does need a key and this will be the item.id that we receive from jsonplaceholder and then we're going to pass the item down to the list item as well the full item itself and that is what our list item will receive so let's go ahead show the file tree once again just to create a new file here and now i'll do that again i clicked away there we go list item with a capital l on a capital i dot js and once again control alt r underscore r a f c e and now we have our list item component i'm going to go ahead and change the div to an l i for list item after that i'll just save for now and i'll come back to the list where we can import the list item i'll click on that to finish the import go ahead and save the list component and go back to the list item component the list item component is fairly simple as we can see we're receiving an item so we want to destructure that at the top and if we look over here we're already mapping through the items we're just not displaying anything so we have 10 users we're seeing 10 dots in chrome for those users but all we want to do right now is print out the full object so we need to use json.stringify and then just pass in the item and this will print out the full object so if we save now we see each user in the webpage i'll go ahead and close the console so we can see this much larger and we're seeing each user because we're on users now let's go ahead and click a button and see if it changes to posts and it does now we're seeing each item that comes from the post data and there's a lot more here for posts i believe 100 compared to 10 users then if we go to comments there should be even more as this should be 500 different comments i believe so we've got all the data and we're displaying it as we expected to so that was part a of the challenge i hope you completed it well and if not i hope my walk through has helped you complete it okay we're ready for part b of the challenge you can see we still have our form with the three buttons at the top users posts and comments and we'll still be switching between those three resources but the challenge is to dive deeper than just printing an unordered list this is a table full of the results and as you can see when we click the button the table changes and we show the different resources so this is essentially the same except we're showing a table and a table requires us to dive deeper into the results instead of just printing out the object now we're going into each property of the object as you can see and we have the id the name and so on now the user's object is deeper than just one object in other words it has nested objects as you can see under posts and then there's even a latitude longitude geo object in here so this is also a consideration as you map through the individual properties of the object now i'm going to give a couple of hints again before you complete this challenge so if you want to go ahead and do this without hearing the hints pause the video now and now i can give the hints the hints for this you're going to need to map through of course each key of the object and to do that you're going to use object dot entries and this is just general javascript knowledge not necessarily just about react so if you don't know how to map through properties of an object because map usually applies to an array you need to look up object dot entries maybe try mdn the other thing to note is that json.stringify still applies if you just specify one property you don't usually have to use that string of five but notice there are nested objects inside of the user's resource when we go to posts and comments not so much we don't really have nested objects here but we do in the users area so here are the comments again no nested objects in the comments but once we go back to users there we see the nested objects and also if you really want to challenge yourself on the css notice that i've now made the form at the top a fixed position so it stays on the screen as we scroll the table and you don't see the scroll bar to go right and left with the table until you scroll to the bottom and then there's the scroll bar once again notice the form at the top stays stationary so this is all about formatting a table and getting it to work on a page so just a little extra css for the challenge okay i'm going to go over the solution now so pause the video and work on the challenge first okay we're now looking at the solution for part b of the challenge and so we need to make some changes right now we've got the code for part a the first thing i'm going to do notice when i scroll in chrome that our buttons leave the page here during the part a part of the challenge i'm just going to go to the css real quick and make a couple of changes one is to make the form that i have a fixed position form so it will stay at the top and then the other is to use just a little bit of padding at the top and remove these other settings from the unordered list and you can see what change it will make to part a for the appearance if i save this and now it looks the same here but after saving those buttons stay where they should be and we can still scroll the page so that's a nice change to the initial css that i had and we're going to use these changes as we change this to a table because we'll still want our buttons to stay here and let the table scroll if need be okay moving over to the app now as we work on the solution for part b the first thing we need to do in the app is just comment out the list we're not going to use that for part a anymore and now we save and our list should disappear so a simple change really in the functional app component all we need to do is change from our list component to a table component so that is what i call it you could call it something else if you want but it just makes sense to call it a table component again we'll just pass the items just like we did with the list to the table component and after that we need to go ahead and create it and then i'll come back and save the app file so i'm going to create a new file here that would be the table component table js with a capital t press control alt and r and now here i'll do underscore r a f c e and now we've got our functional table component inside this it will be just a little bit more complicated than just creating a table element i'm going to create a container and this has more to do with formatting the table with css so the table can scroll and the header will stay in place the form that we have at the top of the page so here i'm going to say class name equals table dash container now inside this div i'm going to create a table and just to keep properly formatted html for the table i'm going to create a t-body we won't have a t-head or a header for the table really but we will have this body now inside the table body we can go ahead and map through the items once again so we'll have items dot mat whoa did not mean that for that to happen items one dot map and so i'm going to now create that without that wrong autocomplete there we go and then item arrow function again a parenthesis not a curly brace there and now we need a row component so here i'm not going to put anything yet i'll just save this and now back in the table we need or not in the table but back in the app we need to import the table so we'll do that here at the top import table i'll click on table and we've got that now we can go back and we've got an error because we don't have anything in our map yet so let's go ahead and add our row component and this will receive a key which will be the item.id and then it's also going to receive the full item itself so we'll pass that item into the row and now let's close out the row component and we also need to destructure items up here above we haven't done that yet and now if we save we'll probably still get an error because we haven't created the row yet and that is what i expected so now let's go create this row component by creating one more new file here row with a capital r dot j s and now control alt and the letter r and we'll have underscore r a f c e and here we have our row it receives the item and the table roll needs a tr not a div so we'll make this a table row and now inside the row we need to go ahead and step through or map through each key of the different objects that we're receiving and this is where it's different than just listing them all out as a json string with json stringify as we did in part a so now we need object dot entries and we pass in item i'm going to go ahead and press ctrl b once again to hide the file tray and get a little more room so object dot entries pass in the item then dot map and now inside of here we can say key value i don't want that parentheses there so i've got one parentheses and then our arrow function and now this allows us this object.entries passing the item and then call map and then we're destructuring the key and the value of each different property as we go through so then here we can reference each one of these and return oops not a curly brace we need a parenthesis we can return a value here and we're going to use one more reusable component and as you might guess in the table we've got a row this will be a data cell i'm just going to call it cell and here we'll once again need a key which is already defined as each pair has a key and a value and then i'll set the cell data is what i'll call this equal to json.stringify and i'll pass in the value and the reason we're doing this with json stringify is because some of these values are nested objects themselves from the user resource they're not so much from the posts or the components i didn't see any nested objects there but with the user resource i did see nested objects so we still need to stringify to go ahead and print that out to the page and then in that regard the address field will have an object printed in that cell i'm going to go ahead and save this file so we can import the row into the table component here we go import row this will be from [Music] dot slash row save that and then show the file tree once again just to create our cell dot j s which will be our last functional component control alt the letter r underscore r a f c e and now that we have the cell it is receiving the cell data and once we get the cell data instead of a div we need a td as you would have in an html table and now we can just put the cell data inside because we've already stringified it in the previous component before we passed it down through the props so now we've got cell data here and we need to go back to our row and import our cell component which is probably why we're getting an error over there say import cell there we go click on that and save and now we've got all kinds of errors over here let's reload and see if that once again happens nope it's all good it just took a second to process so now we have our full table printing out let me go ahead and expand chrome we can see the full table here so as we click posts it changes and it puts the post in the table as we click comments it changes and puts the comments in the table and as i click users it goes back and here you can see the nested objects i was talking about such as in the address field there's also one over here so there's a few different areas now to scroll the table instead of seeing the scroll right away as we would on a web page we scroll to the bottom and then we're scrolling inside that table container that i made and so you'll see those changes in the css there's not much to it but it certainly helps control a table and keep any kind of heading you have at the top at the top and that works out just fine so that is the challenge b i hope you did well you may have done better than i did what one thing i would change if i was doing this in a serious project is i would flatten out our data object such as users so i wouldn't go ahead and put an object in here and if you're curious about how to flatten out nested objects i show a function that does exactly that at the end of my recursion tutorial so if you are or maybe if you are not yet familiar with recursion go ahead and check out that tutorial i'll give a link below as well so you can flatten this out and then every piece of data here would receive its own cell today we're going to be learning about react router and you can see i have a react js blog here and this application is like a full website where react is known for creating amazing single page applications commonly abbreviated as spa sba you can make a full website experience here we have our home page with a feed that has different blog posts we have a page for new posts we have an about page and if we go back to the feed we can click on any blog post and get a page with the full post and the ability to delete the post we're accomplishing all of this with react router and as i click on the different pages the url does change at the top however these pages are not requested from the server these are components that are routed using react router and therefore you get an almost instantaneous response which is also an excellent user experience with that said and this project previewed let's get started on building it with react router i've got a jump start on our react project here in visual studio code and i'll just walk you through this really quickly it's what we did in the first tutorial in the series we type npx create dash react dash app and then we name the folder we want to create like i created 16 tut so you need to be in the parent folder when you do this and then you go ahead and press enter and create react app will set up a new project for you after that use visual studio code to open the new folder that you've created and once you're in this folder you need to add one more dependency and that is the react router and here we'll type npm i and then react dash router dom and then dash capital s and we'll save that as a production dependency and once you've installed that you can press enter of course to do that once you have that installed you can go to your package json file and you will see react router dom included in the dependencies in your package json now from there i've also shown in the previous tutorials how to clear out a new react application but what you want to do is open your source folder and just delete all the files except for app.js index.css and index.js then you need to go into your index.js folder and you want to remove the comments you see starting on line 13 and there will also be an import for report web vitals up at the top and you can remove that and then in the app.js you want to remove both imports at the top and remove everything that's inside of the div with the class name app and make sure you've installed that react router dom dependency as well that we see in package json and we'll begin working on the project let's start by going to the index.js and here we need to import some things from react router so we'll import and then with curly braces we'll say browser router but let not say as router so we can just refer to it as router and then we'll also import route and this will all be from dash router dash dom as we see there and now inside of the jsx instead of what we see here in well we'll keep this part that has the strict mode but then instead of what we see here we'll put router and then we'll take the closing router and put it after the app component so the app component is inside the router but we're going to change this as well let's switch this to route and now let's have a path attribute and we'll set this equal to the root path which is just a slash and then we can specify the component so we'll say component and inside of curly braces we can say app and now we've specified the app component will respond to the root route for our application so let's save this part of the index.js and now we'll be finished with that and everything about our application will now be inside of react router and we can use everything associated with react router including some hooks that come with the react router dom package okay let's move over to the app.js file now and how react router works is it routes components sometimes we'll always want a component to stay on the page like a header or a nav bar or maybe a footer but then other times we'll want the main area of the page to change and react router can route those components based on url file paths but before we can do that we really need to have these components created and import them into our app so we'll start out with some import statements to just list out the components we're going to create we're going to create a header and this will be from dot slash header and then we're going to import a nav and this will be from dot slash nav and then we'll import a footer now these will all be the components that stay on the page even when the other components change so the header nav and footer will be consistent but then after that we'll have a main area of the page actually a main element and the components that occupy the main element will change and one of those we'll just call home and of course it will be from dot slash home another would be a page to create a new post so we'll have that from dot slash new post another one would be a post page where we can see the full page for the post the home would just give us a little clip of the blog post but then we want to see the full details on this page so we'll call this post page and then we're going to have another one that's an about page and that's from dot slash about and then finally we want a page that shows up for a 404 error basically a missing page you've requested a page that doesn't exist and so we need all of those different ones and that gives us five different options to route to in the main area of the page four of them we want as part of the application and then one we would just want to show as an error for a 404 missing a request and after that we need to go ahead and import some things from react router so once again we'll destructure here and we want route we want switch as we'll switch between the routes and then we want a hook that comes with react router and that's use history react router has several custom hooks and this one will allow us to access the browser history but react router does not make requests from the server again it just routes within the app and of course that responds faster so it improves the user experience as well this needs to be from react router dom and after that i believe oh let's go ahead and import some hooks we're going to use in this page too before i'm finished here so let's import use state we'll definitely use state and use effect and we'll make these from react of course okay now that we're finished with these imports we're not running the app yet of course they would create errors because they don't exist but now we can create at least the basics of each of these components to import into our app and then begin to route them with react router i'm going to collapse the open editors here for now and now inside of the source folder we'll start creating our components and so we need a new file and we'll have header.js and now inside of this file i'm going to press ctrl alt and the letter r i believe it's command shift and r on mac if i remember right i believe a viewer told me that but i cannot confirm that right now i'll type underscore rafce and this is because of the react snippets extension that i'm using starts out with es7 if you're looking that up and i'll have a link to that in the description as well but here is our functional header component and it's a basic component here i'm going to go ahead and switch this out for a header element for now i'm also going to put in an h1 and we'll just say header so we can see what this is and save this much and now i'm going to go ahead and whoops that didn't complete his header there we go header now i'll save that i'm just going to press ctrl a to select all and copy and we can go ahead and do that instead of a snippet here in just a second and replace some things so the next one will be a nav so let's create a nav js inside the nav i'm just going to paste everything we had but then i'll select header and i can go ahead and do control d to select all of these change that to nav with a capital n and where do i need nav to not be a capital n that is in the elements there we go so that's an actual nav html element that we see there so you don't want capitals on that otherwise we'll leave this now and save nav and now the next one we want to create is newpost dot js inside of new post i'm once again going to just paste everything in and select header and then switch that to new post i did control d to select all of the header examples but here instead of this new post let's go ahead and just put a main element because that's what this will be and now we've got our new post here to export and then we need a home i guess i could have done home first a new post works inside of home i'm going to once again paste in the full component select all the instances of a header and put in home and then once again i'm going to change the home element here to a main element and save and now we need an about dot js paste this in again select all of the header change this to about and then where about is showing up as a component element we'll just change this to main and sometimes it's not changing that tag as fast as i'd like it to but there we've got another main element for about we need a post page js can paste this again select all of the header change it to post page then select the post page in the element and change that to main it didn't change the ending one for me so i'll do that now and i believe we had a missing component once again pasting in selecting all the header changing it to missing and then changing the element to main okay saving those i think we're still missing a footer component so i'll paste in the header and for the last time selecting all of these and changing the footer to a lowercase footer because that is an html element as well that we want to use a semantic element so we save those and we should have all of our different components let's go back to the app.js and just check the list see if we left anything out no i think we've got everything and now we're importing them into the page so we're ready to use them inside of the jsx of our app before we put any routes in let's go ahead and just put all the components inside of our jsx so we have a header we have nav and now we have all the different main element possibilities so here we go with the home component and then we'll have the new post component and then we'll have the post page component and the about component and then let's even put in the missing component and now let's put in our footer component this will not present an html standard when we launch it but this is in development we will not be showing any one of these five at the same time so from here let's go ahead and open a terminal window and type in npm start to launch a dev server for our react app and we can see how this renders and now we can see our app to the right in chrome and we can see each component has rendered and we have the h1 that we put inside of each component here to identify what it is now we're ready to set up routing so we don't see all of these at the same time i'm going to go ahead and resize visual studio code so we can see it and we can see our chrome version our dev version of the application at the same time and i'll go ahead and close the terminal window and if you recall we already put our app inside of the react router and we're routing the path so now when we route to the app.js this is already inside the router but we always want to show the header and the nav and the footer so we don't really need to route to those anymore because they're already in the app what we do need to do is switch between what shows up as our main element content so we want to put a switch at the beginning of these components that we're going to change out and put the closing switch there now i'll tab these over because they'll all be nested within the switch and now we need to specify routes for each one of these so for the home page we'll start out with a route component here and then we're going to put path equals and we'll put the slash because we want this to be the default with the root path so it shares the path with the app component overall and we're already routing to the app component that contains all of these components so now we have surrounded our home component with the route of path now this could create an issue but i'm not going to show you what it is until we actually have the issue here to demonstrate so for the next one we're going to create a route and this path is going to be equal to not just the slash but also post and now we'll go ahead and put that closing route after it as well so we'll tab in our new post and have the closing route now the next one the post page where we see details for each post this will have a slightly different path because we want to put a parameter in the path and we'll have to use another react router hook to grab that parameter but here we're going to have slash post and then slash and put our id parameter that will identify the blog post and now we can take that closing route and we'll tab in the post page and put the closing route before the about now with about and missing these are two components that i do not expect to be passing any props to so we can do that just a little bit differently if you remember how we handled the route for the app itself inside the index js we can do the same thing here so we can say route and then let's specify the path and the path for about will be slash about and then we can specify the component and here i'm just going to put about now i'll do something very similar for missing so we'll have route and the path for missing is going to be a catch all so if none of these others have applied essentially this wild card here the asterisk will then catch what isn't caught above it and this component will show so spell component correctly and put missing in and so for our last two routes we can just put those all in one line we have about and missing now i'll go ahead and save this and let's look at the changes in chrome we see header nav home and footer okay so that seems right we went to home but now let's try to go to post in the url bar and we still get home so that's an issue we don't want home we want the new post component to then show so the problem here is this is like a waterfall inside of switch and as soon as it matches something that's what it delivers well the path with the slash is going to match all of these other paths really except of course missing and it would match that too if if it hadn't already matched ahead so it matches the first one and then that's what it routes to so we need to add a keyword here and this keyword is exact so let's save our page now and now post delivers the new post and that's great but what if we had a post with an id of one we're wanting to see the first blog post so we put in that parameter we still get the new post and that's not what we wanted we wanted the post page so we also need to add the exact keyword to our slash post route for the new post because this other one shares this route as well and now you can see we get post page after i saved that change so we needed to add the exact keyword to both of these and now after post page there's nothing else that would match post so let's go ahead and check our other routes i'll switch to about in the url and we get the about and now i'll switch to abouts well that would probably still match about now let's see nope it matches missing so it can't be just something with this and then whatever else is after it like an s for abouts so then our wild card grabbed it and that's exactly what we expect so any route that doesn't exist will not be matched and then it will default to this wildcard so all of our routes are working as expected now with the main routing for our app complete now we will talk about adding links and how react router handles those and we'll also add some custom hooks like use history that i've indicated up here already with the import and how react router works with those and grabbing parameters from urls and we'll do all of that as we build out this blog application in the next tutorial okay we're picking up in this tutorial right where we left off from the previous one that introduced react router and we have all of our routes now specified inside of our app component here but today we need to build out the blog application and then work with react router to handle links and also work with react router to pull parameters from the url and also we can pull in some custom hooks that come with the react router package like use history that i've already put in the imports up here at the top to work with the browser history there is also one that will allow us to pull those parameters from the urls so we've got a lot of work to do today let's get started we'll start by going to the index.css right now i just had in the default css from the create react app i'm just going to select all of that by pressing ctrl a and i'm going to paste in my css and again there will be a link to the github repository in the description below so you can get all of this css as well because i'm not going to go over all of the css as i want to focus on the react part of this tutorial but the css will be available to you and of course i encourage you to experiment with css and style this blog how you would like it to be you don't have to use my styles but i'm going to go ahead and apply that now you can see the changes over here in chrome have already applied somewhat and we're not seeing a whole lot but we need to build out our components and then we'll see more of these changes as we apply the class names that exist so i'll close the css for now and our first component is a header so let's go to our header component we don't have too many changes to make in the header component but it is going to receive a title prop and then also the header component will have a class name attribute and this needs an extra s and a capital n there we go and this is going to be header as well for the class name and then instead of saying header here in the h1 it's going to actually use the title prop to display so we can save that and we might get an error because no it's just blank because we haven't passed the title prop okay so if we go back to the app.js here in the header we can now pass the title prop and we'll just say react js blog and we'll save and we should now see that in the top and we do so that is our header for now let's move on to the nav js which is the next component and we've already got the nav element now nav is going to receive search and set search because we will have a search bar in the nav as well as the links for the menu and instead of an h1 now we do want to have the nav elements but now instead of the h1 we're going to have a form here for the search and then we'll also have a menu our nav also needs to have a class name attribute and we'll just set that equal to nav so in the form where we have our search we'll have a class name we'll set that equal to search form i'm going to hide the file tree with control b is in boy and i can see a little more code now and i'll say on submit as we often do with forms we're going to prevent the default i believe and that needs an anonymous function and then we take the event and have prevent default and now we need to close out the form tag now we have the closing form tag as well now inside the form we always want to have a label even if we don't show the label we can use css to take it off the screen but it will be part of the dom itself and then screen readers can use it so we'll just say search here with the html4 attribute for the label and that needs to match the id of the input and then we can close that and i'm going to say search post because the label just essentially needs to describe what the input does and then we'll have our input and now i'm going to put all of the attributes for the input on separate lines well we know we need an id that's searched so it matches the html4 above we also want to set the type and that's going to be a text input and then we want a placeholder and this will say the same thing as the label so we say search posts and then we'll have a value and we're going to set this equal to search and search is what we passed in up here as a prop so this is going to be a controlled input and then just like a controlled input the on change also needs to set the search and we do that with an anonymous function with the event and then we set the search i have the e dot target dot value and that makes this a controlled form input and now we can close that input out and i'll go ahead and bring this back to line it up and we can save that much now we're going to have to go ahead and create the search and set search back in our app to pass those in but before we do that we finished the form let's go ahead and create our navigation as well so an unordered list and now each list item can be a navigation link but we haven't imported the link from react router yet so let's do that at the top and that's import link from react router dom there we go and we can save that now we can use the link as we import it and links render to anchor tags just like we would see in html with like an a with an href however this tells react router don't request this link from the server just route to the proper component and so now instead of an href we have a two and we'll set this equal to a slash for our home page and so there's the link to home and now i'm going to use shift alt and the down arrow to make a couple of more links and now we'll link these to other pages so we'll have a link to post and a link to about and of course we can change the wording here to match post and about and this will handle the links in our page so now we save those and we see the different links up here the css has already applied itself so now let me click post and yes we went to our new post page click home we're at the home page click about we're at the about page our links are working now we still haven't created our state with search and set search so let's go back to the app.js and do that very thing we've got our use state here so inside the app function we want to define both search and set search and then we will set that equal to use state and we need an empty array for those as we start out and we'll save that and i'm wrong i don't want to use an empty array there i want to do that for the search results for here i just want to do an empty string we'll be changing the search string but then we will have search results that will be stored in an array while we're in the app.js and we're creating state of course we're going to need some data to search through and for now we will hard code our posts for this dev environment and we can worry about hooking those to an api later so we'll also have posts and set posts for our blog post and this will equal use state and this will have an array in it so i'm going to hard code four posts for now and i'll just paste those in and you can see it's an array of objects and each object is a post and each post has four different properties we have an id a title a date time and a body and again this will be linked to in the repository but you can create your own test post as well if you just follow this pattern so now we've got posts and set posts using state as well we'll save that and let's scroll down and let's go ahead and create the other state i was talking about which would be search results and set search results and we'll set that equal to use state and this will also be an array but we'll just start out with an empty array and we'll save those now if we scroll down just a little bit in our nav component we need to pass in both the search equals search and set search equals set search and now our nav component is complete and we will be able to search the posts here once we put in just a little more functionality while we're right here in the jsx i'm going to go ahead and set posts equal to posts for the home component so we'll be passing those posts in because they will display in a feed there i'll save this and then press ctrl b so i can see the other files over here and i want to work on the home component let's click on home over here with the links so we can see the home component and then it's going to receive the posts and we have the main element here and let's put a class name on the main element this class name is going to equal home let's save that and see if we see a change yes we do it now pushes everything down and we see the footer down here at the bottom so the style for this is set to a flex box and everything in this column should be equal except the main element is set has a flex grow value of one so it grows and fills this out so when we provide the main element with the proper class it now fills out our entire page okay inside the h1 now we don't want this home at this point so we can or i said h1 inside the home element or the main element of home we don't want the h1 we want to actually work with the post to display them and what we'll do here is check the posts length with a ternary and we'll say okay if they have length now we need a parenthesis what we're going to do is display a feed component and the speed component will receive the post as well so we're drilling those down with prop drilling and if it does not have length then we need to do something else here so another parentheses and let's go ahead and put a paragraph here set the style and we'll need two curly braces and we'll give a margin top of 2ram and then we'll have the closing of the paragraph and on this extra line here we'll just say no posts to display and we can save that and we might have an error because we haven't created the feed to import yet so let's go ahead and create a quick feed component feed.js inside this i'll just do control alt r and then underscore rafce we've created the feed component it's blank but that's fine it will at least eliminate the error and now we'll go back to home and we need to import before we can eliminate that error so import feed from dot slash feed and now the error should go away yes and we just have a blank page because feed is empty it looks like we have something else oh it says feed is not defined let's go ahead and reload and i think it'll be all right yes now we're good so now we can work on the feed component let's click on feed in the file tree and feed is also receiving the posts and as you might guess inside of the jsx we need to map through those posts but first let's remove this div and let's just make it an html fragment here so we can do that with by just eliminating the words so we've got the less than greater than and a slash so this is just called a fragment in react and that works as well and now we'll have posts dot map and then we map through each post with the arrow and now we need a parentheses not a curly brace and now we're going to use a post component so a reusable component for each post and it will need a key as you map through [Music] so that will be the post id but then we'll also pass the full post to the component whoops not posts just post and then we can close out this component and that's essentially what we need for the feed component here but of course we're going to need to import post once we create it so i'll save this and it should create an error again and then we need to go ahead and create the post component inside this component ctrl alt r then underscore rafce and we have the post component although it's empty i'll just save it and now back in feed we need to import the post [Music] save that the error should go away but now it'll still be empty because we haven't done anything inside the post so now let's work on the post component in the post component starting at the top we're going to need to import link from react router once again let's react router dom oh it didn't do it there we go react router dom and now that we have that we know we're receiving a post so we need to destructure that at the top and now we'll make this div an article and then we'll give the class name here as well class name equals post and now let's make a link i want this with a capital l so it's a react router link i'm going to press control b again to hide the file tree and with this link we'll have a2 and now let's make this an expression and we'll use a template literal inside so it will be to the post and then we'll give the post dot id so this will take take us to the individual post now inside the link we're going to have an h2 and inside the h2 we'll say post.title and then we'll also have a paragraph we'll give this a class name equal to post date and this is going to have the post dot date time value that is within each post and now both of these will be linked to the specific post address with the url that passes in this parameter of post id now underneath this link let's go ahead and give a class name equal to post body and we'll close that and now we can give an expression here and inside the expression we're going to put a ternary statement here so we'll take the post dot body and then we'll get the length of that and then we'll say if it is less than or equal to 25 if that is true we want to just display the full post body that means the entire post has 25 characters or less but if it is false then we'll go ahead and start with a template literal and then we can have the post body again and then we'll slice from the post body we'll slice the first 25 characters and after that we'll put an ellipses like three dots at the end and that way we're only showing a snippet of the full body because we don't want any more than 25 characters in the initial feed and then you can click on the full link above here and see the full post so let's save that and now we can see our feed with each post and of course i've used lorem epson in each one of them and so they're all the same right now but we see they go the first 25 characters and then we get that ellipses and this should be linking to each individual post so if i click my first post yes it takes us to the post page that we haven't designed this component yet but that should show the details and the full post body for the individual post that we're supposed to see as it grabs the parameter out of the url so let's work on this post page now i'm going to press ctrl b to show the file tree select post page and i'll press ctrl d once again to hide the file tree now inside the post page we're going to import a couple of things at the top so let's just do that right away import destructure here and we're going to import use params which is a custom hook that comes with react router dom and we're also going to import link but it just says from react router i don't know why it's saying that so we also want it to be from react router dom here at the top okay once we've got those imports ready to go we're going to receive a couple of things as props one of course is the posts the other is going to be a handle delete function because we're going to offer a delete button on this page as well so those are the props coming into the page and now let's go ahead and define the id inside the function and this is going to be equal to use params and we said id here because that's what we called it in our route back in app.js when we defined the parameter for post page so that's what you need to do if you named it something different you need to also have this named differently so that's what's defined in the route and then once we have the posts here we need to get the individual post we want to display so let's say post equals post dot find and now we get the post and here we'll take the post dot id and then we'll set it to a string because it is really numeric so if we didn't set it to a string we would only be able to use two equals which you could also do if that's your preference i prefer to use strict equals when i can but in order for me to do that here i need to set that to a string to match the id that is also going to be a string coming from the parameter so once again if you don't set this to a string you'll need to go to non-strict equals just the two equal signs so it's up to you whichever you do this is the way i'm doing it and we've defined the specific post that we want to see now now with the main element here inside the jsx let's set the class name equal to post page and then after that we're going to have an article and let's give the article a class name equal to post [Music] let's go ahead and get rid of this h1 element and now inside the article it depends if we have a post display or not so let's say if we have a post and then use the two ampersands which is a way of saying okay if the post is true essentially if it exists then we're going to display this and inside of our curly braces after the ampersand let's put a fragment once again and so now that we have a fragment for the parent we can put our other elements so we'll have an h2 and inside the h2 i'm going to say post dot title and then the next one will be a paragraph with a class name and here it's going to be the post date and inside this of course we'll put post dot date time [Music] and now i'm just going to copy down with shift alt and the down arrow change this post date to post body and here of course it will be post dot body and then finally we need our delete button so this will be a button and let's give it an on click let's set this equal to with a curly brace and then we get an anonymous function and inside the anonymous function we're going to call handle delete but we need to pass in the post id then after that we can close out the element and display on the button we can just say delete post so now we know we need a handle delete function that is coming in as a prop and it receives an id so we can save all of this but we're not quite finished yet oh and something is undefined cannot read property find of undefined and i believe that is because we're not passing anything yet to post page from the app.js that's not it let me go ahead and show the file tree click on app.js and if we come down here to post page we haven't passed in those props yet so let's say posts equals posts and we're also going to have handle delete equals [Music] handle delete and save now we'll probably still have an error because we haven't defined handle delete let's just come up here to the top above the return and we're in the app.js we'll quickly define handle delete and then we can add more details later and we'll just put details in here a little bit later i believe empty is okay for now let's see if we get past that error yes we're past it and we got a display let me go ahead and it says handle delete is not defined i think it just needs reloaded yep and now we're good back in the post page though we haven't quite finished our definition yet because what if we don't have a post so we need an option if post is not true essentially with the exclamation mark here it does not exist but we've somehow got to this page i'm just going to quickly paste in what i'll put here and you can see we have an html fragment once again as we use in react i'm going to hide the file tree so you can see everything and inside the fragment we have an h2 with post not found and then i just say well that's disappointing and we put a link that says visit our home page and so that's why we've imported link above as well and so now we're using the use params from react router to get the parameter and we're using link to provide a link back to the home page if it doesn't exist so let's save this and you can see use params is already working we wanted my first post and that's what we got if we switch this to number four we should get my fourth post and that's what we got as well but if we go ahead and request post number five that doesn't exist we get our portion here where the post doesn't exist and it says post not found well that's disappointing visit our home page and the link works i'm going to press ctrl b to show the file tree again go to app js and now we need to go ahead and finish defining our handle delete function what's going to happen is we receive the post id here so then we can just define our posts list and we'll set this equal to posts dot filter and there we have a post and if the post dot id is not equal to the id then we'll include it in the posts list so we're filtering out the post that has the id that we have passed in from there we can just set posts back to the new posts list that doesn't have the post with that id and now we want to use our browser history we click the delete button but we're on the individual post page so we can do that with the use history hook that we are importing up here now underneath where we set the use state let's go ahead and hit return and we'll just say history is equal to use history and after we've defined that we can use it inside of our handle delete function so we'll say history dot push and we'll just push in the route to the home page and this will take us back to the home page once this is completed so as part of the function we're accessing the browser history with react router and then we're serving the component instead of requesting anything from the server we're serving the component that is routed to that home directory listing with this saved let's go ahead we've got our posts over here on the right in chrome i'll click my third post here's my third post i'll click delete post it deletes the post and takes us back to the home page instantly and notice there's no third post now because we have hard coded our posts in our state when i reload the application completely we get my third post back so you can play around with this and delete them right now and they will come back but everything looks and works as it should we now need to work on the new post component that we will see when we click post that allows us to create a new post but before we do that we need to create some more state inside of our app.js that we will be using inside that new post component so we'll say const and here we're going to have post title and set post title this will be equal to use state and this should be an empty string and then i'm just going to copy that down and we'll also have post body and set post body so we'll change those to body and that's also equal to an empty string and now that we've defined both of those we're going to pass both the post title post body and the set post title and set post body all in as props to our new post component but we also need a handle submit function as we submit a new post so here is our handle submit and we'll just make an empty function right now once again and come back and define it when we're ready let's go ahead and scroll down to our jsx where we can pass all of these props into new posts so it's receiving more than most of our other components or it is receiving more than all of our other components actually so we'll have handle submit is equal to handle submit and then on the next line we're going to go ahead and have post title is equal to post title we'll copy that down and then we're going to have a set post title is equal to set post title we'll have post body equal to post body and finally we're going to have set post body equal to set post body we'll save those and we'll go straight to the new post component to begin adding everything we need to hit inside new post we've got a lot to destructure as we pass in all of those props so i'm going to add it on an extra line here say handle submit and then we've got post title set post title [Music] post body and set post body all coming in as destructured props i'll save that and now we're ready to go ahead and add a class name to the main element i'm going to set this equal to new post and if we save we should see a change there we go the main element has taken over with the formatting let's go ahead and change the new post h1 to an h2 and let's put a space between new posts but we'll leave that on the page and the next element to add in the jsx is a form as we'll be submitting a new post and the class name here will be equal to new host form let's give this an on submit but it might be different than you expect instead of a prevent default here we're just going to reference handle submit now the interesting thing about this is it still receives the event we don't have to have an anonymous function and specify e inside if we just give a reference to a function like this it will still receive the event and we can refer to that inside the function okay let's put a label element for our input in this label of course we'll have an html4 attribute and this will be for post title now we're not going to hide this label either we'll go ahead and show this on the page and here we'll have title and now we can put our input for the title and again i'll put the attributes for this input on separate lines so it will be equal to post title as it needs to match the html4 attribute and the type is going to be text and we'll make this required so the form will not submit without it and this will be a controlled input so we'll set the value equal to post title and that means we also need an on change and we set the unchange equal to that anonymous function with the event we'll have set post title equal to and we need a parenthesis e dot target dot value so this is a controlled input and that hooks it all up and we can close out that input but we need the post body as well so we need another label element with an html4 and this is going to be post body and we'll just say post here for the label and now this won't just be an input that's a text or type text we'll just go ahead and make this a little bit larger with a text area and let's put the attributes for the text area on separate lines as well the id will be post body we don't need to set the type as a text area is text doesn't have that attribute we can make it required and then let's make this a controlled input as well so the value is going to be the post body that we received as a prop and then we need to put an on change set that equal to once again an anonymous function and inside the function we'll have set post body and have that be e dot target dot value and now let's close out that input and we still need a button so i'll scroll up just a little bit and inside the form let's put a button element and the type will be a submit button and then on this we can just say submit and that should finish out our form and now we see everything over here in the page we've got our title we've got our post and we've got our submit button we can't test this yet though because we really haven't defined our handle submit and it looks like i haven't defined the set post title so i need to see what's going on with that and i see the problem we've got an extra equal sign here let's eliminate that and now we're using set post title as it should be so if you followed along and had the same typo i did please change that everything looks good now we'll save this and we need to go back to the app.js and define the handle submit function as i've mentioned the handle submit reference still receives the event even without the anonymous function specifying it back in the new post component so here i just put the e for the event in the parameters and we'll reference that here and just call prevent default at the very beginning of the function after that we need to define the id for the new post so let's set the id equal to and let's check to see if the posts array has a length and if it does that mean posts already exist it's not empty then we need to get the last post and we do that with posts and now to reference the last post we'll say posts dot length minus one because it should start counting at zero so if you get the length you've got the count of all the posts you need to subtract one to actually get the last post and after that we'll reference the id property of that last post and then we'll add one to it but if posts do not have link that means the array is empty and we need to just give this post an id of one now that we've defined the id we also need to define a date time value i'm going to set that equal to an empty string for now and now we need to import a dependency package that we haven't imported yet i'm going to open a terminal window with control and the backtick once i've done that i need to go ahead and press ctrl c to stop running our dev version of the react app right now now in the terminal window i'm going to type npm i and then date dash fns which stands for date functions and then i'll tag dash s so we want to save this as a production dependency and go ahead and press enter and when this finishes installing i'll come back our new dependency has finished installing we can press control b to look at the file tree and check the package json to make sure it is there and yes date dash fns is there so i'll close the package json i'm going to hide the file tree again and at the top we need to go ahead and import this dependency as well so we'll say import and we just want the format so we'll destructure that from date dash fns and save and now i'll go ahead and come down here to the function we're working on handle submit and we can apply the format in the date time we'll go ahead and type format and then we need a new date object and then we can specify the format and here i'm going to use four m's and then two lowercase d's and then four lowercase y's so as you might guess we have month date year and then we're using pp and this is going to specify a time i'm not for sure why they use that format but that's what it is you can look up this package at npmjs as well or npmjs.org i believe to get the details on the date dash fns package but this is what i pulled out for this project okay now that we have that we're defining the date in the format that we want it we need to create our new post [Music] remember we are submitting a new post here and we're handling the submit and the first thing we have in the post is the id and then we'll specify the title and that's going to be the post title and then we can specify the date time that we've set and then we'll specify the body and of course that's going to be the post body and that is our new post now we need to create a new array with all posts so we'll set this equal to the posts that are in state plus the new post and now that we have our all posts we can go ahead and set the posts as our new state and then we'll set the post title in the controlled input back to empty so after we've submitted the new post we won't have to delete what we've submitted to create another one we'll just set that to empty we'll do the same thing for post body we'll set it back to an empty string and then finally we once again need to access the history and push and let's go back to the home page after we've created a new post so we're not just setting on the new post page again so now that we save all of that we have stopped our dev environment with the react app to go ahead and install that date time dependency where we pulled out format or out actually the date functions dependency that we're using for date time so we need to once again start our react app with npm start to try this out and our app is back up and running let's close out the extra tabs we have and this is the current one where our app is now running now notice we got a warning here search results and set search results are assigned values but they're not yet used so we need to go ahead and make the functionality for our search bar work let's close the terminal and we'll scroll up just a little bit here and we can see search results and set search results have not been used yet right now they are using state and they're just assigned an empty array so we need to change that and we've already imported use effect if we scroll up i believe we'll see that there's all of our posts but yes we've already imported usefx so let's go ahead and use effect now to work with this search bar and search results so we'll put use effect of course use effect has an anonymous function and then after the function we have to define dependencies for use effect and when any of the dependencies changed is when use effect runs again well we'll put that with posts and we'll also set that to work with search and so now as our search input provides new data we could go ahead and provide new data here for the searches we can essentially filter the posts that we have down to what matches our search and so that's why those are both dependencies we're going to define something here called filtered results and we'll set this equal to the posts dot filter and now we can just say for each post and inside of this we'll need our parentheses and let's go ahead and put this on a separate line just so we can see everything and now we'll have inside the parentheses another set of parentheses to specify the post body and we need that because then we're going to add a dot to lowercase and this will set everything in the post body to lower case and now we've got the outer parentheses and then we can put dot includes so we're checking to see if the the post body includes and by setting everything to lower case we're not being specific about whether it's capitalized or not our search will work either way and then we can use our search value and also set it to lower case so it could possibly match and there we've got our full filter for the post body so we set the post body to lower case we also set the search to lower case and we're checking to see if the body includes what we're searching for now after that this of course this yellow one here or gold if you will highlights our entire filter function so i could put this on a separate line or even underneath after that we need to use an or which is also considered a short circuit operator but this is ore and we want to do the same thing but not just for the post body we also want to do it for the post title so if either one has what we're looking for this is what we'll search for and contain in the filtered results so now i'll put that closing one back there at the end and we've defined our filtered results after that let's set the search results but instead of just setting them equal to the filtered results which we do need to put in here let's think about our posts right now the oldest post is always at the top we'd rather see the newest post so let's go ahead and set this to reverse so our search results are reversed now this still won't change this right now until we change what we're sending to our home component so we save that and we have the search results but we don't see anything happening yet if i type in f or f-i-r-s-t nothing is happening here with the feed and that is because our home component below is receiving the posts and not the search results so let's change that let's still refer to it as post as we do throughout the child components but here we'll pass in the search results and now let's save this and quickly we see it is now showing the fourth post at the top instead of the first it's got the reverse order and now we should be able to search posts so i'll type three for third and yes that works two for second f for first and fourth and they both show but if i put an i it's just the first post now they all have the same body right now so let's see if we can add a new post call this test post and we'll make a short one and we'll add that and we've got an error let's see what's wrong with our handle submit function because we were trying to submit a new post and i think i see the problem we created a new post object and then i was in the mode of creating objects but our posts need to be inside of an array so if you followed along with that problem that i created please fix it and this should be an array there we go and let's change this other curly brace to a bracket also now we have a new all posts array and that should be what we expect let's save and let's try to create this new post again so we'll just say test and inside of here we'll just say yay because we want a short post and now we've got our new post and the new post shows up at top and it's less than 25 characters long so this goes back to where we set the ellipsis if it was 25 characters and then we put an ellipsis after it but if it's not we just show the full post and that's what we're doing here with noaa ellipse so everything works as expected now i'm going to show the file tree again we've really only got three more components to complete before we're finished and that is the about component the missing component and the footer component they don't really receive props so we should be able to do this fairly quickly i'm going to go to the missing component first missing.js and at the top of missing we need to import from react router the link again so we can link back to the home page and we'll say from react router dom and after that i'm just going to highlight the main element here inside the jsx and paste in what i have and you see a class name of missing on the main element we get an h2 page not found instead of post not found that we had for our post page when a post was not found and then we linked back to the home page so let's save that and we should be able to test this by just putting anything after our url there so let's just put test and we don't have a test route and it should bring up our missing and it does page not found visit our home page an interesting thing to note let me go ahead and delete the third post now we've deleted those and again they load statically when the app reloads if we go to a missing page like we did there for test now the app essentially reloads because after we've routed to the missing if i go back the third post is there again so that's worth noting that the app essentially reloads now of course you wouldn't be using with stat using static posts with a production app but that's what we're doing here in development and that's why the third post may come back or any post you've deleted after you go to the missing page now let's go to the footer js and inside the footer js there isn't anything to receive as a prop again i'm going to select everything including the return and just paste in what i have and here i'll press alt z to wrap just a little bit so you can see anything that might be missing but you can see i'm just defining today as a new date before the return in the component and then i'm referencing that with the copyright and i say today dot get full year so i get the current year and now let's save this and our footer should change and yes it does it's a little bit hidden down here and i'm not sure why but here we can see the full footer right now if i expand the page and we see everything and it's static as well so we can scroll the main area of the feed and the footer is still visible there now i'll resize and for some reason it's just scrolled off here just a little bit but it wasn't doing that for me previously okay so there we've got the footer and now we need to go to the about about.js and i can click the about link over here and we can see we still haven't added anything for about yet what i'm going to do is just highlight the main element and everything and paste in what i have alt z again so you can see the full thing and again we changed the about to an h2 we added the class name about and then we just put in a small statement about what the project is we'll save that and now our about page is what we expect it to be and it fills out the space so about works we have our new post page we have our feed we can go to the details of any specific post in our feed and everything is working as we expect it to and this is a great start to this project in the future we're still going to add additional features to this application and that includes a custom hook that we can create for react and it also includes the context api and fetching data from an api with axios so much more to come today we're talking about setting the height and width of your react application i prefer to use flexbox for this however i'm sure there are other methods today i will show you mine a react application provides a few differences from just building html and css from scratch we have to consider how a react application is structured so let's begin with that and we've got the index css open here on the left and i've got the react app this is the react js blog that we have been working on lately in the learn react tutorial series this is here on my right you can see it is centered but it does have a width problem we're using react router to change the main content i'll show you what i mean when i click on post the width of the app changes just a little bit here i have the max width set to 800. when i click on about it even gets wider so really the application is changing based on the content size in the main area but let's look at the css i have i'm importing a font at the top i've got my reset i've set a default font size here in the html element and then in the body i've set a min height of 100 units and so it's at least the full height of the visible browser here but then there's the app component and we have the app class and the width is set to 100 as we look at the header and the footer they're also set to 100 width here on line 37 and it it's the same for the nav menu and all of the main elements that we change out here with different classes and they're all set to 100 so why is the width changing well we have to think about the structure of react applications and let me pull up the file tree on the left here in visual studio code and i'm going to click on the index js and now i'll hide the file tree so we can see more of this but what we often fail to consider at least i do as or i did as a beginner with react is that everything is still attached to a div that has an id of root so even though we have a component with an app class our app component it is still being inserted into this other div so we have another container to consider and that is why we are not seeing a consistent width here we haven't set the width or done anything with that container with the id of root so let's go back to the css now i'll briefly show the file tree click on the index css hide the file tree and here we are and right here in between we should do something between the body and the app class because the body will default to the width of the page which is 100 without us even putting that in there however the app cannot expand to 100 width of the page because it's inside that div container with the id of root and it is not set to expand and we can right click on the page over here and choose inspect and we'll pull up dev tools and now with dev tools open and i highlight the body you can see it has the full width of the page but now when i highlight the div with the id of root you can see it does not have the full width of the page so that's what we need to change so instead of having the justify content center and a line item center here in the body we can make the body a flex a display of flex but then we want to go ahead and add the root id and we'll give this root id not only a display of flex that justifies everything in the center with the content and a line items but we also know that the root div is a flex item because it's inside the body and we can set it to grow so it will expand up to the available width which would expand it for the full page so let's go ahead and save and now that we've saved that of course it immediately expands and uses up the rest of that room so if i pull this over a little bit maybe we can get to where we have some extra i can't get it wide enough there i tell you what i'm going to do is expand the entire browser so now we have some width on the left and the right because i have set a max width of 800 pixels here for the application so now when i highlight div inside the dev tools we see it is the full width of the page again and now we have to expand that and highlight app and we can see app stops at 800 pixels but div with the id of root is now the full width of the page just like the body is but we have to set that here and we have to let it grow if we use the flexbox approach that i'm using and now the app can expand up to the full 800 pixels that i have allowed in the code for it now if i bring this back and i can just close out devtools here if we come down to the app and i get rid of this max width of 800 pixels i'll just comment it out briefly and now save the application itself should expand and it does and it just fills the entire page so that's what the max width does it gives us that nice little margin at least when we have a screen that is larger than a tablet i'll save that and put the margins back on the left and right so it stops at 800 pixels and now let's see the difference if we remove this flex grow from the root the div with the id of root i'll comment that out and save and we can see a couple of things happen one is it's no longer centered because we didn't put a justify center or a line item center either one of those did not go up here in the body we removed that so it's no longer centered and then it doesn't grow it doesn't expand to fill everything here so we need it to grow and then it will automatically be centered and we can see the change here now now that we've discussed the width of the application and i hope you have a better understanding of how that works how a element can also be a flex item while it is still a parent like this div is and we've set the display to flex but is also a flex item and has a flex grow property here in the css but now that we've discussed the width let's quickly discuss the height as well because once we're into our app component all of these other components are within we've got the header the footer the nav bar and then all of the different main elements that change out when we click our links and of course notice now that the width stays consistent as we click between these now that we have addressed our div with the id of root so now the height well flexbox defaults to a flex direction of row so instantly inside the app component we not only want to use a display of flex but we want to tell it we're working with a column and then it begins to stack everything up on top of each other where we have the header nav the different main elements here in the area and the footer the height of 100 viewport units set inside of the app component is really the one that takes over so the one that i have up here for a min height in the body really isn't necessary i can comment that out and we can save and we won't see a change because everything inside the app component makes the rest of the containers grow so the div with id of root and the body element itself will grow to accommodate the app so really i have my min height of 100 units here in the body just out of habit it's not necessary for this application but i usually include it it's just one of the things i always start with but the height that's really making things happen here is the 100 units viewport units for the app component now if we change this and we don't set a height it will just expand to the content once again so we can save this and now notice the footer goes ahead and gets pushed down because it grows and if we go to the about page that doesn't have nearly the amount of content we can see that it shrinks and since we have set this to be justified in the center and align items in the center it's completely centered right now instead of at the top and just shorter so we really need this set height for the application and the other thing we're doing is once again using flex grow and we're using it for all of the classes that apply to these different main elements whether it's the new post the about or the feed here and we can see that i believe in my css on 130 where there we go flex grill line 130. we've got the different classes here for the home feed new post post page if we go to an individual page that it goes ahead and grows this body out and that's because it's a flex item or each one of these are flex item and we've set flex grow to one so that goes ahead and expands the page notice we also have overflow dash y set to auto and that helps us with our feed so the footer stays in place and we're able to scroll the feed here in the main area i want to scroll back up really quickly and find the footer class that i set because here it is there's an easier way to center things when you know you only have one thing to center and that is with display grid and you can place content center and that's exactly what i do with the copyright notification here in the footer so i've set that to a display of grid and placed the content center as well this has been a very quick overview for how you can use the full width of the page and the full height and of course align things in the center if you want to limit like set a max width or even a max height you can center things with flexbox fairly easily and as i mentioned here at the end you can also center things with a grid display fairly easy so it's not a full tutorial on flexbox or grid but when you're working with the react app there's just a few extra considerations and i know you may want that application centered or you may want it to take up the full page and you definitely want the pages that you use say if you're changing with react router like we are with this application to have that consistent width and you don't want your application to be an accordion and change widths based on the page that you go to in this tutorial we will be adding the axios package to our react js blog application and it will help us request data from a development api that we will set up with json server axios actually makes requesting data easier than using the fetch api so let's get started i'll go to the file tree and i'm going to click new folder and the first thing i'll do is create a folder named data and inside this folder i'm going to create a file named db.json and then inside the db.json we're going to put data you could actually copy it and modify it from our app component and i'll open up the app component here as you can see we have a static state right now for posts set in the app component and here we have four test posts and there are objects inside an array you could just copy these and put them in there i'm already going to paste in my formatted json and you can see it's just a little different than we have in the state here we have an object and we've given the object the name posts or the property posts and then the value for this property is the array with all of the posts like we have in the use state in our app component right now notice each of the properties are within quotes and that is not the case in our javascript over here in the app component so as you bring those over ensure that you are formatting them like you see here in the db.json i'm going to go ahead and save this and now that i have the db.json file inside of our data folder i'll go back to the app.js and i'm just going to remove everything in the post state and replace it with an empty array which is how we want to start out and save and that is really all we need to get json server up and running so i'm going to collapse the source folder now and click on the package.json because we're going to add axios as a new dependency so after we install it you should see it listed inside the dependencies of your package.json file quickly go to chrome and here at npmjs.com then slash package slash axios you can see the details for axios and there's documentation here as well and i will put a link to this in the description for this video going back to visual studio code i want to open up a terminal window in windows i press control and the back tick you could also go to the terminal menu at the top of visual studio code to do that as well and get rid of the help menu there that i opened by mistake and now we can install axios as a dependency so i'll type npm i and then axios and dash s is a habit of mine it's actually not required because it will save it by default and it will save it as a production dependency so we can just do npm axios i'm going to press enter and when this finishes installing we'll go ahead and get started applying axios to our project you can now see axios has been added to our package.json file and we are ready to begin adding axios to our project let's close the terminal window and now let's open the source folder we see in the file tree and let's add a new folder inside the source folder and let's name the folder api inside the api folder let's go ahead and create a file name posts and then we'll put js of course post js and now that we've done that we can import axios from axios and now we need to set the base url that we'll use for axios throughout the project so we can just set export default and say axios dot create and then a parenthesis and then a curly brace now on a separate line we can define the base url property and we'll set this to our http slash localhost and then we need port 3500 that we're going to launch our json server on and that's essentially all we need in this file and now axios will continue to use this base url and of course when you would take this project live you would need to change this base url to whatever url you got at your host okay now that we've set the base url for axios let's go ahead and open a terminal window and inside this first terminal window let's launch json server so we'll type npx and then json-server dash p and then 3500 for the port and then dash w for watch and that will be data slash db dot json press enter and that should launch our json server instance and after we get that started we'll go ahead and launch our react app in another terminal window okay to open a second terminal window i'm just going to click the plus sign here and now you can see we've got a little tree on the right that shows our different terminal windows in this terminal window i'm going to launch our react app just by typing npm start and once we get this started we shouldn't see any posts because we've changed the state but then the react app will show any changes we make as we add axios into our application and now our application is loaded with no posts to display as we expected since we cleared out this static state i'll go ahead and resize the window so we can see it on half of the screen and then i'll resize visual studio code as well and now we can work on our code on the left and view chrome on the right i'm going to close the terminal windows although they will continue to run and we can reopen them at any time i'm also going to collapse the open editors area over here in visual studio code so we can see a little bit more of the file tree and we're ready to begin in app.js okay in app.js i'm going to hide the file tree quickly i do that by pressing ctrl b in visual studio code i'm using windows it may be different in mac and linux but what we need to do at the top is import our api so i'll just add another line under where we imported format and here i'll import api and this will be from dot slash api but remember that's a folder we can see visual studio code shows us that so we'll select that and then we have posts inside the folder so now we've imported the api and we can use it in the application i'm going to scroll down and underneath our use history line here on line 20 i'm going to press return and start another use effect and this use effect is where we will fetch our data and we only want this to happen at load time so our dependency should be an empty array inside this use effect we need to define our fetch function and i'll call this fetch posts and it should be an async function inside the async function we're going to have a try block and of course to follow that up a catch block where we catch any possible error and now we need to simply define how to use axios and we'll define a response just like we would with fetch and we'll set this equal to a weight api remember that is the axios instance we're importing and then we can use get and this is where axios becomes very easy to understand we actually use the verbiage the words that we would in a crud operation possibly in api usage so like http uses get post put delete there's patch and a few others but we're only going to use the basic crud operations so get would be our read operation in crud and so now we just need to say what endpoint we want with that base url and of course we only have one endpoint with this application and its posts so we'll go ahead and define that now this replaces fetch and then what's so nice about using axios instead of fetch is axios automatically creates that json we don't have that second step here where we have to define data and set it equal to response.json another thing that is nice about axios is it will automatically catch the errors when they are not in the 200 range of http responses so before where we would have said if the response dot okay is false with the exclamation mark there we don't have to do that either axios will automatically catch anything outside of the 200 range so what we can do now is just set our state with set posts because if we get to this point an error has not occurred and we know it's already in the 200 range and our data is going to be in the response dot data now you may see some at this point would say okay if we have the response which we should at this point it should only be in the 200 range and they might say if we have response dot data and you could do this to be extra careful if you want to i'm not going to do that because right now i know i've got a response in the 200 range and if i have that our json server is absolutely going to send data back and if you are working with somebody else that's developing the back end you might already know that you will be getting a response in that 200 range if not that is how you could check for that to make sure you have a response and response data i'm just going to leave it like this and we can set that response right here for the posts and that's as simple as it is really that is using axios to get the posts and setting the post state right there now axios catches those errors that i mentioned and what we can do this is directly from the documentation we can say if this is not in the 200 response range then i'm just going to copy and paste some things directly from the axios documentation and axios will provide these errors and so you could log all of these different things if you wanted them so you would get error dot response dot data right here and so if your back end was sending a message at this point you would actually receive the message if that was the property like that it just depends on what the back end is delivering when it's not in the 200 range so you have to know what you're dealing with on the api that you're working with to actually know what property to pull out of that data you could also get the status and the headers but then axios will also catch other possible errors here so what we can do is say up above this we can say if error error.response that means we've got a response property well here just need the one and now put the curly brace at the end and this is when you'll see these responses but then we can say else and this means error.response is undefined so if that's the case we can just log the error message and i'll copy and paste this in but we've done this before this is a template literal and now we're getting the error message property and so here we know we did not get a 200 or we did not get a response at all i'm sorry here we know we didn't get a response in the 200 range but we got a response from the back end api here there was possibly no response or we got a 404 or something else occurred but this catches all the other errors right here again this is directly from the documentation for axios and it handles those errors very well so we can pull out extra data if we need to and we can define between those all of that said our function for fetch post is now defined but what we still need to do is call fetch posts here inside of the use effects so let's save this and now we have our posts once again over here on the right and so our use effect works as soon as the page loads and of course our development server loaded the page as soon as we saved our changes and we now have those posts now if you remember we can post a new blog or make a new post on the post page in our application so the next thing we need to adjust in our application to use axios is the handle submit function handle submit has a few lines of code that are just a little longer so i'm going to expand visual studio code we will come back and show the application after we complete this code edition for axios and of course this would be the create portion of a crud application the c in crud where we're creating a new post so after the line 54 that defines new post we need to start our try block here and of course i'll delete that ending curly brace but everything that we see here is really going to be in the try block because we won't want to make any of those things happen if we fail our attempt here but we do need to go ahead and catch an error again and here instead of everything i posted above from the documentation for axios we'll just console.log and we'll once again have a template literal so i'll say error and then inside here we will put the error dot message so at least we know we're grabbing the message and logging it you could expand upon this you could put what i did above in the use effect when we're fetching and handle the errors how you want to but at least we are acknowledging we might get an error here and this is what we'll do for it in this development application so in the try block we need to define a response once again so we'll say cost response and we'll set that equal to await api but now we'll use post instead of get because we're posting a new uh blog post and then we need to define the endpoint posts and then we're going to pass in the new post and that is the data we're sending after that let's well we don't need a new line let's just look at all posts because we need to alter that we're going to take all the posts we had previously and now instead of the new post here we're going to use the response dot data this should be the same as the new post actually it should just be the api sending us the data back and confirming that we'll go ahead and use response.data here instead of the new post and then we can set the post to all posts we can still empty out our controlled form that has the title and the body and we can use history.push to go back to the actual blog and see the full list in the feed and so nothing else really changes we're just using axios and it's really that simple to send the new data and then we're going to update the state with the actual response we get from the api as well and get that dot data out of the response so let's save that and i'll resize visual studio code again and it looks like we have a problem here because i didn't put async at the top of the handle submit so we can't await without it i'll put async on line 50 where we define handle submit and we should be good so let's make a test post for tutorial and here is my test post and here it is with that working let's go ahead and set up the easiest part of the crud operations which is the delete we've completed the read which was git and create which was post let's go ahead and add the handle delete i need to remember the async above here as i had to add later inside of the handle submit but we'll put it right away here with handle delete and then we'll start our try block and as before everything we already had is going to be inside of our try block then after that i'm just going to copy the catch block from the other function and put it here you can expand on that as i discussed with axios documentation if you want to and here inside of try we will not get a response we just want to await the api call delete and now i'll put a template literal because we need to pass in the endpoint post but we also need the specific post id to be passed along and after that everything else should essentially be the same so let's go ahead and save and now let's go to the detail page for this test post for tutorial and delete the post and everything seems to be working as it should for the delete operation as well and now the most complex operation of the crud operations we've got create read and delete completed but is the update and we haven't really added an update component to our application either so we're going to need to do that but first i'll create the function and let's just call this handle edit because we're going to edit a post and again this will be async and we need the id now inside the handle edit we're going to need some new state as well so let's scroll up to the top and just like we have the post body and post title let's create an edit title and edit body so i'll copy both of these and come down here and let's go ahead and just select post title both times and then change post to edit and i'll change this one to a capital e and we can do the same here for post and change it to edit and change this one to a capital e as well so now we've got edit title edit body set edit title set edit body and we'll use those in our function here for handle edit we're going to start out though needing the date time and the new post much like we do in this function above so i'll just copy both of these down and in here i will paste both of those the date time will change or it will not change actually the new post let's call this updated post and now instead of post title i'm going to have edit title and let me expand visual studio code for now instead of post body we're going to have edit body because this will be a controlled form where we make the edits as well and so we need those pieces of state for the controlled form now we can start our try block and of course after the try block we'll have the catch block and i'll just copy that down as well so now we can put our information inside of the try block we'll start with a response and we'll set that equal to a weight call our api and now we'll call put we could use patch if we were updating specific fields but here we'll essentially be replacing the entire post so we're going to use put and we'll put in the endpoint posts but again this will need to be specific to the id of the post after that we'll be passing in our new data which is the updated post okay now that we have got the response back from axios and the backend api we use set posts here but this will be just a little more complicated than we have previously completed a set post like we did up here where we just passed in all the posts after we defined the post because we need to use map that is if we didn't use map we would be creating a array of posts here but we'd still have in the old post as we added in the new post as well we need to eliminate that old post and just add in the new information so with map we'll have each post iterated through and map creates a new array which is exactly what we need so we'll check the post id and it is equal to the id we passed in this will be a ternary statement and we'll say okay let's use the response data which is the new post information if the id is equal to the post id passed in if not let's just go ahead and pass in the post as it is so that means only for where the post ids match will we pass in the new data which is essentially the updated post but we're going to use the response data here destructured with the operator right here and if not we'll of course pass in the post as it currently exists because that does not need to change so that will update our post state and now we'll still need to set edit title back to blank and then we'll also need to set edit body back to blank because again we don't want to hold that data over for the controlled form in any way after that we'll use the history once again and push so we go back to the main feed so we can see our edited post amongst all the other posts and save that should complete the handle edit function let's go ahead and resize visual studio code just to make sure there were no errors as we saved but it looks like the application went ahead and loaded as expected right now we have no way to get to a new component and we don't even have the edit component yet so let's create the edit component and the pathway to get to it i'm going to show the file tree again in visual studio code i'll highlight the source folder and then i'll create a new file and call this editpost.js once i've done that i'm going to go ahead and expand visual studio code again i'm going to press control alt and the letter r to use my es7 react snippets and here i'm going to type underscore r a f c e to get that functional component you don't have to do that you can type this out as well if you do not have that extension i'll link to the extension in the description below okay we need to make some imports at the top of this component the first one is going to be use effect and after use effect we'll say from react then we'll also import a couple of things from react wrap one is use params and the other is link and it's not just react router it's react router dash dom visual studio code wants to help but it's got to get that part right okay in edit post we're going to be bringing in some props here and there's enough i'm going to put them on a separate line we'll need all the posts we'll need our handle edit function we will need the edit body the set edit body will need the edit title and the set edit title after that we can start in on our function and this is really a combination of our new post page where we created a new post with a controlled form but also our post detail page where we pulled in the post detail from a parameter and that's why we're using use params so we're going to start off here in the function and i guess i came down one line too far i'll create this id just like we did in our post page to get the post detail and we'll use params to get that id attribute that we're going to set in the route and then we need to get the specific post so we'll set this equal to post find and once again this is just like we did on the post detail page and this will be post dot id to string because when it comes out of the param in the url it is a string and that's what we're matching and so we have to set the post id to string to actually use strict equals you could just use the double equals and not do the two string part so it would be your preference which way to go there but now that we have the post and the id we can go ahead and use effect and this is when this loads we need to pull in this data and set the state for that so let's go ahead and say we're going to put in post set edit title and set edit body as the dependencies and now inside use effect we'll actually need to set the state for both of those we'll say if we have a post because there is a chance the page could be requested and a post would not exist so we'll say if we have the post set post title and this will be post title and then oh i'm sorry not set post title it would be set edit title here we go edit title and then set edit body and it would be post dot body here now that we have those we've set the state and so the form will already be filled out and our controlled form will be ready to edit the existing post the body of the page itself will be much like the new post page so let's just go to the new post page and select from the beginning of the main element to the closing main element and then go back to our edit post page where we can just highlight the divs and replace those with what we have on the new post page we'll leave the class name new post the same so the form here is formatted just like it is on the new post page so we won't change that however after the main element let's go ahead and put a curly brace and say if we have an edit title so the post will need to exist for us to have set an edit title and then we can put a curly brace afterwards but you can see visual studio code doesn't like this right now because in jsx you have to have a parent element and currently we do not have a parent element set we have oh i didn't mean to put it after the main actually so let's change that and put it after the form and tab this curly brace over not getting the tabs i want with the current error here and the error means we need to set a fragment in here as the parent element and now you can see visual studio code is much happier and doesn't have all the red lines so let's tab this over and then tab over here we go because our h2 and our form or neither one was a parent they were sibling elements so that's why jsx and visual studio code would not accept that now that we've done that let's change this new post title to edit post and let's go ahead and update the form a little bit we can keep the same class name here new post form we want the same formatting from css but handle submit will not be called an onsubmit instead here we will prevent default as we often do with the form inside of the on submit call for the form so when that happens that means inside the button here we're going to need to have an on click and we can set this equal to an anonymous function and inside this anonymous function we'll call the handle edit and we need to pass in the post id here and that's why we're not doing that in the on submit area now for our controlled form to work we need to go ahead and update some of the names here instead of post title would be edit title instead of set post title it would be set edit title and that would be the same here instead of post body is going to be edit body instead of set post body it's going to be set edit body we could change the ids here but we know this component will not load at the same time as our new form or our new post form so we don't really need to they'll only be one on the page at a time so this should work for us once we save these changes we've created our new component but it is still not being routed to in the app.js we still have no way of getting there so let's go to our app.js and let's scroll down to our routes and let's copy this post with the exact path and paste it below we can remove the exact we're actually going to change the path to edit and then we'll need to have the id parameter afterwards so there we have edit and slash id parameter this will not be new post it will be edit post and now let's pass all the props we need here we need posts equals posts instead of handle submit this will be handle edit and now instead of post title we'll have edit title i should have selected both of those edit title i will do that now so here instead of set post title it will be edit title post body will be edit body and set post body reset edit body now we've got all the props being passed and we've got the correct route in we just need to create the link and have a way to go to that route let's quickly go back to our edit post page i just thought of something that we didn't complete we have the if edit title exists which essentially is saying if the post exists we're going to go ahead and show the form but if not and there is the chance that a post will not exist and then the page could be requested we need to go ahead and update this this shouldn't be post title this should be edit title but here this says if we do not have a title essentially if the post does not exist we need to pass in our post not found information here which is where we use the react router link to go back to the home page so now we've completed the edit post component and back in the app.js we completed the routing and so now that we have the routing we just need to create a link to the edit page well we have a delete button on the post page so that would be a good page to possibly put another button that would allow us to edit as well directly above the delete button we can use link which we've already imported above from react router and set this to and now we can put in a template literal and pass in the edit path and here this will need to be the post dot id now that we've created the link inside the link we can put a button let's give this a class name to differentiate it from the delete button here we'll say this is the edit button let's hide the file tree because i'm going to run out of room and after that we go ahead and put some text on the button we'll just say edit post that looks good let's go ahead and give the delete button a class name as well we'll set this equal to the delete button and we need the ending quote there we go and we save that and that's really all the change we need to make to the post page we may need to tweak the css just a little bit but this should be fine now one more late addition to the app.js that i didn't think to do when we put in the route would be to go ahead and import the edit post component at the top so let's fix that by coming up here right under the post page we'll say import edit post from slash edit post and save now let's look at our application see if we have any other errors everything looks like it's still loading correctly i'll just reload to make sure there we go let's click on testing a fourth post here we have an edit post button yes we might want to change the color with those new classes we added and differentiate maybe add a little space it looks okay if we click edit post we've got the post here ready to edit you can see the form is already filled out so let's say some more testing paragraphs instead with a few dots click and it looks like we edited our post just fine i'll click that and yes some more testing paragraphs looks good we could possibly go back to the home and create a new post and here this form is empty but it's a controlled post so we'll say another post once again and we've created another post so that's all working well we can possibly edit this post once again with an exclamation mark and yes it's working just fine the only other thing we might do to check for errors is right click and choose inspect or you could press ctrl shift in the letter i and we'll check the console to see what the console is telling us as far as any errors or warnings but no it looks like it is clear we can reload and see if react gives us anything new nope it is fine so we're good to go from devtools there so let's go ahead and go back to visual studio code and then click on index.css and if you scroll to around 200 or around line 200 from what we've already had we can make just a few changes here first of all on my line 203 i'm going to remove the h2 missing h2 and post page h2 and then i'm going to put a comma and i'm going to add new post and the paragraph for the new post class as well and instead of margin bottom i'm going to make this margin top so we can save that change and we should see that on the post page nothing has changed here but if we come back to home and go here we edit the post this looks good too now let's say let's try to edit a post that doesn't exist and the post not found page looks good as well now let's go back and let's here we are on the edit post page we want to fix these buttons actually this is on the post page and when we would click edit post it would take us to the edit post page but yes we want to fix these buttons and let's take the background color red out of the button definition and so now they're just plain old buttons here they both still have a white text color let's create the class delete button that we applied to our delete button and make it red and now that will change and then let's go ahead and create this edit button class that we also applied but instead of red we'll change that to the same color as the nav menu [Music] and now the edit post and delete post buttons look a little better we just need a little space there so beside the padding that is 0.5 ram let's say the margin right 0.5 room as well and now we get a little space between the two buttons everything seems to be working well we can read posts we can create new posts we can delete posts and we can edit post as well so we have applied axios and all crud operations to our application and we should be good to go and move on to custom hooks in the next tutorial today we're talking about creating custom hooks in react you can see i've got visual studio code open and i've got the blog project open that we've been working on in this portion of the learn react tutorial series i've already got json server running as you can see here in the terminal and in the other terminal window i've got our react app running so i can close the terminal window and if you're not sure about setting those up please view the previous tutorials in the series okay with both of those running and visual studio code open i'm going to minimize it at first and here is our blog application and we're going to apply a custom couple of custom hooks that's a tongue twister a couple of custom hooks that we're going to create today but before we do that we need to look at the rules of hooks for react and there's just a few to remember here one a very important one is only call hooks at the top level so don't call hooks inside loops conditions or nested functions and then a couple other things to remember call hooks from react function components and call hooks you can call hooks from custom hooks so those are the places we can call them we can't call them inside of other existing react hooks like use effect and we can't call them inside of regular javascript functions either but we can make our own custom hooks and then we can use other hooks inside of those so with that said let's look at just a couple of other things very quickly i want to call your attention to this website and i'll give a link to it in the description below but it's a collection of react hooks because that's what these are they're kind of like utility functions but they're in react and they all start with use which is another rule of react hooks actually that we need to define them with the word used to start out with and they're like recipes so there can be more than one hook that accomplishes the same thing just because it's had a different author and this is a good site to search for those on also there is this npm page that's react-used and it contains several react hooks as well that i think are good so i'll leave a link to this in the description below as well i just wanted to draw your attention to those before we come back to our own blog project and create these hooks so now let's get started in visual studio code here in vs code i've got the app.js file open but this is just to have the place in the tree open that we're going to create our hook actually what i want to do is select the source folder and create a new folder inside of it i'm going to call it hooks now you can see the little icon i've even got here with the hook so if you get the icons i believe it's vs code icons extension that i have you'll probably get something similar we can create files of course now inside this new directory or folder if you will and i'm going to call this file use and that's how we want to start out with every react hook and then window size this is a simple hook that will allow me to display how a hook is used to start out with then we'll create a more complicated one but we'll start here with use window size now inside this hook i'm going to import use state and use effect because we can use these hooks inside of our custom hook and now i'm going to say const use window size and set this equal to an arrow function now inside the function we'll start out with a window size and a set window size so as you can imagine this is going to use state now we'll set the state equal to something we haven't seen previously in this learn react tutorial series and this is an object and i'll set a width and i'll set this to undefined because that's truly what it is at this point it is an undefined value and the same for the height so this will get both the width and the height of the browser so we can identify that in our application now after we've set our initial state we'll use effect as well an arrow function there now for the use effect dependencies that we'll have at the bottom we just want this to run at load time and essentially that is the only time this will run just as we've discovered with use effect in other parts of our application now let's define a function right here inside of use effect and we'll call this handle resize so this is if the window is resized and we'll set an arrow function here and now we'll set the window size or set our window size state inside of this and we'll start out with the width and this will be window dot inner width and then the height will be window dot inner height and that will essentially track the value of the window size if this function is called into action okay now that we have that we need to go ahead and call that in our use effect so we'll have handle resize called into action because we want it to run at load time and that's what will happen here now that's the only time this would actually run this function handle resize so we'll get those initial values so how will we get the values to continue to adjust when the window is resized well we'll do that with an event listener like we would in regular old javascript so we'll add an event listener to the window window.addeventlistener and we'll listen for the resize event and then we'll handle the resize call that function into action and that's essentially what we need to get those values every time because we added this listener at the beginning with use effect when it was loaded so it only adds it once but there is something else we need to do and it prevents a memory leak in our applications and that is to remove the event listener fortunately use effect has a cleanup function that will only run when the dependencies change for use effect and so we know the dependency won't change here this is only at load but it would actually happen on a say if i change the file and reload so we'll be able to see that happen but also it would happen when the application closes out it would essentially run the cleanup function and remove that event listener so we can do that i'll just define cleanup here with a camel case capital u set this equal to an arrow function and we'll refactor this in a moment because we can make this a little simpler but i want to put a console log statement in here so you can see what happens and we'll say runs if a use effect dependency changes and then we'll see that in the log when this runs and then we'll call window dot remove of that listener and this will be the same resize event and we'll be removing the handle resize function from that event and now we can save this but we haven't called cleanup into action yet we just defined cleanup so all you have to do and use effect to use the cleanup is the return at the end so we'll just return cleanup and now that would be called into action okay we're almost finished with our custom hook but before we finish we need to remember to go ahead and return the window size in our hook this is not in the use effect which stopped right here but this is in the custom hook where we're returning the window size value and now all that is left to do is export default use window size and we've completed the custom hook file if we scroll back up we can see we start out we have use state use effect we define the hook we set the state we use effect and then the key part here is we want to call it once at load time to call the function we've defined here handle resize but then we also want to add an event listener and so any time the resize event fires we continue to call this handle resize function and then another portion of this is the cleanup function and that's also important to prevent a memory leak so now we have completed this entire custom hook and now let's use it in our application we'll go back to the app.js file and inside the app.js file where we have our imports underneath the api import we can import use window size and you can see visual studio code helped out here it is from dot hooks slash use window size so that is exactly what we need and we can save our file there but we're just not using it yet after that we need to come down underneath where we've defined history and we'll just pull the width out remember we had an object that had width and height we only need the width for what we're going to accomplish here so we'll use window size but we'll destructure and just pull the width value out so now we can save we'll go ahead and remove this extra line above the or underneath the import of use window size and then i'm going to scroll down where we're going to use the width and we're going to pass it into the header so now we just want width equals width and that should complete the changes to the app.js file now we need to move on to the header js file let's go ahead and add width into the destructured props at the top of the header file but now we also need to do an import at the top we're going to import fa laptop f a whoa that changed that completely we said something too close in our date f fns package here we need f a laptop and then we need f a table alt tablet alt sorry i spelled that wrong tablet alt and finally fa mobile alt and these are from react dash icons slash fa and i am not so sure that we have react icons installed in this project yet let's take a look at our package json and we do not have react icons installed yet so i need to go back to the terminal window there we go because it doesn't have react icons we got an error where we had react running i'll stop that temporarily and i'll do npm i react dash icons and we'll install react icons quickly react icons has finished installing and we can see that in our package json added to the dependencies so now i'm ready to restart the react application as well and with the react application restarted we'll go back to visual studio code and i'm going to close out the terminal window again and go back to the header js file here's where we're importing some icons from react icons and these are font awesome icons that we're going to use in the header based on the width so now that we have the width destructured along with the title we can use it here inside of the header and so now let's base this upon the value of the width and so i'll type width and then we'll say if it is less than 768 and this will be a ternary statement we're going to use the fa mobile alt not mobile mobile alt there it is icon and then we can say if the width is less than 992 of course this is the false indication so at this point it is already 768 or greater but at the same time if it's less than 992 we can say oh we'll start another ternary statement and then we'll say if this is true we'll have the fa tablet alt [Music] and then finally if that is false we'll just show the fa laptop value there it is and this will essentially indicate in the header which size we are showing so if we're showing a mobile phone view it should show a mobile phone icon if we're in a tablet view it should show a tablet icon and if we're in a laptop or anything larger than a tablet actually it should show the laptop icon so let's save these changes and now let's go ahead and look at our application and see if the changes are in place and yes right now we have a laptop icon in the top right now let's go ahead and open up devtools so we can change the sizing and i will go ahead and start to shrink this down and now it's already a tablet it's a tablet icon if i make it a little larger the laptop will come back there's the laptop tablet and now let's go ahead and change in dev tools to a phone i'll choose the iphone 678 plus and yes we have a mobile phone icon so everything works as expected and i could also shrink it this way and now we have the phone icon tablet icon back to the laptop icon so our custom hook is working and we're sending that width value in and changing the icon based on the width value okay i've changed the screen view now i have visual studio code on the left i have our application running on the right and below i have dev tools open so you see the console here at the bottom and you can see i'm getting a warning that says fa mobile is defined but never used that is because somehow i not only imported fa mobile alt but also fa mobile and i didn't know notice or realize that so let's go ahead and remove that and if we clear out the console and reload we should not get any further warnings that's good now let's go to the use window hook that we created and the one thing i had not demonstrated yet was the cleanup that should log to the window so this cleanup function now if we just make a change to the file because again there's no dependencies here so it just really needs to reload and then we save we should see this message runs if a use effect dependency changes and that's the only way to change the dependency here because we have no other dependency it just runs at the load time so that shows you that the cleanup function does indeed run now we can actually refactor that cleanup function because i wrote it out to allow for this console log and then we defined it separately and i just called cleanup here but what we could do instead of that is just return an anonymous function so let's put in the parentheses and then an arrow for an arrow function and now we can just take this line that removes the event listener and put it right there and that would be the same as having no we need the add event listener the same as having this cleanup function that we call by name or by reference let me hide the file tree and you can see it better so this is our cleanup function and if you see a return at the end of a use effect that is exactly what it is it is a cleanup function and it removes the event listener so this accomplishes the same thing just a little refactor not to be confused with the return at the end of our custom hook but this one is inside of the use effect okay now that we have added a simple custom hook and if you search those links i've given in the description below you should find some other recipes for use window size it's a very popular hook let's do one now that is more complicated but also very popular and you will easily find more literature or more videos on it and that's a use fetch hook but we'll add a twist because we're not just going to create a use fetch hook since we've already added axios to our project we're going to create a use axios fetch hook so let's start by creating a new file and we'll name this use axios fetch.js with that said i'm going to hide the file tree so we have more room to type and now at the top i'm going to import and i'll import use state and use effect once again and these are from react and then i'm also going to import axios from axios and now we'll define const use axios fetch this will be an arrow function and it will accept what i'll call a data url now inside this function we're going to have several pieces of state here and here instead of saying posts we want this to be generic so we could use it in other applications so a custom hook is much like a utility function so here we'll have data and set data and we'll set that equal to use state and we'll put in an empty array then we also want to have a fetch error and a set fetch error and i'll set this equal to use state and it can just be null then we're also going to have a loading state so is loading and set is loading [Music] and this could also be equal to null to start out with now let's create our use effect so we'll start with use effect i have an anonymous function and now use effect we're going to define we'll call this is mounted and we really want the component to be mounted and not attempt to apply something after it is unmounted which would also be a memory leak so we'll set is mounted to true and we'll check that status as we apply things the next is to go ahead and define a source and this is part of axios and you can see this in the axios documentation but we'll set a cancel token so we can actually cancel the request if for whatever reason the component is unmounted and we set it by axios dot cancel token dot source and so that is our source now we can define our fetch data function inside of use effect we'll set this equal to async and here i'll just call this url as we define this function it can sometimes be confusing to accept a parameter we're going to use and then use that same name when you create a definition because this isn't where we would use it it's just the definition of the function so here i'll call this url and inside of our fetch data function the very first thing we want to do is set is loading to true and then we will go ahead and try and inside the try block we can have a response and we'll set this equal to await axios.get we'll have our url and now we need to go ahead and apply our cancel token and this will allow us to cancel the request if we unmount the component and of course we can handle that in the cleanup but we need to set the cancel token here so here's the cancel token sent with the request and after we get a response we want to check once again to see if the component is mounted and now if it is mounted we can set the data and this will be response.data as axios has and then set the fetch error to null and as i think about this null that we used above i actually think for is loading instead of null we can set it to false to begin with and then we set it to true when the function is called and then we can set it back to false otherwise okay so we have checked to see if it is mounted and we have set the data and we've set the fetch error to null because there was no error otherwise so now we've finished our try block and now we need our catch block and once we catch an error and i'll scroll up just a little bit we once again need to check if is mounted and if the component is mounted just like above we can set the fetch error now instead of the data and this will be the error.message and we'll set the data to an empty array because we received an error and now after that we'll have a finally block once again scrolling up just a little bit and inside of the finally block so this will always happen once again want to check if the component is mounted but here we'll just say is mounted and so if is mounted is true then we can go to the next part and let's go ahead and use a timeout here just so we can see the loading message we'll come back and change this you wouldn't want this in your final project here you just want to do this to display the is loading message and make sure it's working so we're going to set is loading to false but only after two seconds so that will allow us time to actually see the is loading message and verify that it is working here as we're in development process now that we've completed the fetch data function we want to go ahead and call fetch data and remember the hook receives a data url as the actual parameter so the data url is what we'll pass in in the definition we used url but above it actually receives the data url so that's what we will call fetch data with after we call fetch data let's once again go ahead and define a clean up here camel case cleanup equal parenthesis arrow function and we'll say console.log here we'll just say cleanup function so we know it's running after the cleanup function we'll set the is mounted to false and will cancel the request now if the request is already completed no harm no foul but this will only run once again whenever a dependency changes for the use effect with that definition completed let's go ahead and return the cleanup function and now we want to set the dependencies for use effect as well and the dependency here will be the data url that is passed in to use effect or pass actually passed in to the custom hook we have use axios fetch as the data url but then if that changes we once again want to run use effect so we'll put that in as the dependency with that complete we can return three things from our custom hook and that's the data that we receive that we have in state the fetch error and is loading so we'll need all three of those things returned from our custom hook and then once again now that the hook is complete we need to export default and we'll use axios fetch and save let's do a quick review before we move on and put this into action so we've defined our custom hook we've imported axios and use state and use effect we set different states here at the beginning of the custom hook we're receiving a data url and then we defined our use effect hook inside here and we set an is mounted status to true and we also define a cancellation token for axios and then we set the fetch data function we defined it and inside of this function we have a try block a catch block and a finally block we're constantly checking to see if the component is indeed mounted and if it is we can go ahead and take action after we've requested the data we can set the data state and of course set the error to null and if we catch an error we're going to set the error message and set the data to empty array and finally this will happen no matter what whether we're successful with the data or we have an error we'll go ahead and see if the component is still mounted and if so we're going to set loading is loading to false and right now we're doing that with a delay just so we can test our is loading message we call that into action with the url received by the hook and eventually we can call the cleanup function here that will cancel a request if the component is unloaded during the request and it will also set is mounted to faults we're returning the data possible error and the loading status and that is our use axios fetch custom hook so now let's put it into action i'm going to show the file tree quickly just because i want to go to app.js where we can actually apply our custom hook and the first thing we need to do is import it so underneath our import of use window size we can import use axios fetch and this will be from dot slash hooks slash and then use axios fetch there it is and we can save that much but after our import we need to come down to where we've defined the width and use window size and just underneath that we can set const and then equal to and we can destructure what we're receiving from axios fetch and we've got the data the fetch error and is loading and now let's go ahead and hide the file tree so we have some more room and this may still extend a little bit but we're going to set this equal to use axios fetch and now we need to pass in the full url this is not like when we set a base url before we set up our custom hook to be reusable in other applications and so there is no base url currently set so what we need to do is put in the full url for our data and this is json server url you need to change this in a production application but here we've got localhost port 3500 slash posts and that is the full url that we will pass to the use axios fetch now besides that oh and here i set an equal sign there that's not what we need there we go an extra equal sign please remove that if you had that so we've got data fetch error and is loading from use axios fetch but we also need to remove this use effect that we were currently getting our data width because that would be redundant so we can go ahead and remove this from our project but now we have data but we don't have posts so there is one more step after we get our data back and that is to go ahead and set the state as we're using it in the rest of the application we could just use data if all we wanted to do was to display the post data on this page but we're clearly doing more than that with it in the application so i'm going to set a use effect here and once we have this use effect just inside of it i'm going to say set posts equal to the data so it updates our post state and we only want to do this when the data changes and that should complete everything we need so let's go ahead and save and now we have everything in place except we're not using fetch error or is loading but notice we did get our posts once again so that said let's go ahead and put fetch error and is loading to work we'll start by scrolling down and we need to pass these to our home page so here was our exact path with post and home but here's what we need the exact path with the slash we've got post equal search results let's go ahead and break this to another line now because we're going to have more than one prop to pass along and we'll say fetch error equals fetch error and we'll also have is loading equals is loading now that finishes the changes for the app.js file but we need to go ahead and make some changes in the next file and the next file is the home file so let's go to home.js and we need to destructure what we're passing in so we've got fetch error and is loading at the top let's go ahead and hide the file tree once again let's start by just removing everything we have between the main elements and starting over in this file the first thing we'll do is to check if we have is loading so if is loading is true we can put two ampersands and then we can set a paragraph let's give this a class name equal to status message and if we haven't defined status message we will shortly we'll set this equal to loading posts and that's essentially all we need so if that is true we are loading posts so we'll save that of course we're not seeing anything right now but we will here in the near future on the next line we'll check to see if we have a fetch air once again two ampersands another paragraph with the class name equal to status message once again but also let's set a style right here and set this equal to a color and it'll be red because we know we have an error and now inside of the paragraph we can set the fetch error to display and it will be red when it displays now that we have defined that line we can add one more line to actually show what we hope to show and that's not the is loading or the fetch error message but the actual post themselves so here we'll say if we do not have an is loading message and we do not have a fetch error message and now we'll go ahead and say if the lowercase please post length let's set a ternary statement and here we'll set the feed component and this will be posts equals posts i'm going to go ahead and start wrapping some lines here by pressing alt z set post equal to posts then we can close out this component and after we close out the component let's go ahead and put the false part of the ternary statement and this would be a paragraph let's give once again the class name equal to status message and inside this paragraph let's just say no posts to display and save and we once again have our posts now everything seems to be good but when i reload there's our loading post message that's what i wanted to see and it lasts for two seconds and then we get the post so that is correct let me make this bigger now that we're not looking at the console once again i'll reload loading posts and then we get all the posts later so that is good let's go back to the app.js and let's just make an error on purpose so we know that our error message is also working and i'll save after creating a problem with the url and we got a network error let's once again reload we got loading posts and a network error and maybe we could eliminate that where we're not getting a loading message at the same time as the error message so let's go back to home and let's set this equal to no is loading and we do have a fetch error if we save let's go ahead and reload loading posts network error now that looks correct so let's go ahead and go back to our application fix the url and save now we get loading posts and then we get the posts and that's exactly what we want i'm going to show the file tree once again go back to our custom hook let's find that here use axios fetch there it is hide the file tree and let's get rid of that timeout in here so we can just have it to set loading to false and we know about the cleanup function we don't really need the console log here so let's go ahead and remove that as well but since we're doing two things let's define this as cleanup and then call it here and leave that like it is we are setting the is mounted to false and we're also canceling the request with axios so let's save that and everything is good it already reloaded and now when we reload we barely see that loading post message at all so we've created two custom hooks today use axios fetch and use window size and you might find different versions of these out there again they're like recipes or utility functions that you can pull into different projects and use them again and again now remember the rules of hooks there are several and i will link to those in the description below this video okay today we're talking about use context in the context api we're not adding any new functionality to our blog application we're just going to refactor to use context instead of drilling props down because that can become unwieldy and we can see really that our app.js is full of code we've put in all of our logic as well and so we've just been passing it all down this once again might not be the most efficient but it certainly helped you learn how to pass props down to components and we've been drilling those props as the statement goes however we're going to eliminate all of that today by refactoring and we'll have a much neater app.js file and we'll be able to subscribe to context and use the use context hook to pull that information in so let's get started we'll highlight our source folder in the file tree and here i'm going to create a new folder and call this folder context inside the context folder i'm going to create a new file i'm going to call this data context you can have more than one context per application i'm just going to create one today as we have a small application but imagine having a user section where the user entered information for example and you might want a completely separate context where you manage state with that here we're going to go ahead and start with an import statement and we need create context i'm going to import this from react so while i'm here i'm going to go ahead and import use state and use effect as well because we'll be using those inside of our context now from vm is not correct i want from react and now that we have that i want to go ahead and define my data context i'm going to set this equal to create context that we just imported and this will have an empty object inside to start out with from there say export const and i'll define our data provider that will provide the data to our different components and here we'll have a parenthesis and then inside is a de-structured children and this will refer to the components that are within the data provider and then the data will be available to the children of the data provider so now that we have defined our data provider let's go ahead and put a return statement in it and inside the return we'll have a data context dot provider and here we'll have a value and now two curly braces and i'm going to go ahead and press enter to have an extra line and then we can close this out with a greater than symbol but this is where we'll put the different values what have been props that we've been passing down we can now pass through the data context dot provider and our data provider will provide it to the different components as we request them with the use context hook and so we'll add that all of that in just a minute right now let's finish this and here we need to have children in the jsx and after that we need to close out the data context.provider in the jsx we can save that much and i have that formatted but we still need export default data context here at the bottom after we save that we really have our skeleton for our data context we need to move state and anything else we want in here that we will provide through the data provider let's go back to the app.js and now we need to import our data provider and this will come from dot slash our new context folder and inside the context folder is the data context and now we can use the data provider to provide data to any of these components right now of course it's still a little large here as we have all the different props that we're drilling down we will clean this up in a little bit but what i want to do is just essentially put the data provider here around all of the components and then the components within can subscribe at will to the data provider now that we have that i'm just going to highlight everything and tab them in because the data provider would be a parent to all of the components within and we can save that now the data that comes from our context from the data provider will be available to all of the components within if we choose to pull it in using the use context hook let's go ahead and scroll up here in the app.js and start moving some of our state and information over to our data context while we still leave it here as well so we can keep the app working during the transition here as we refactor so i'm going to highlight everything after the components here so i've got the route switch and history from react router dom and everything below it except the data provider and so down to axios fetch i'm going to copy all of that and put these import statements in our data context as well now of course we don't need the use state and use effect from react we've already got that we won't need the route and switch but we will have use history here and then we've got format now when we get to our api we have to consider where this file is we have data context inside a context folder so that's different we need to come up out of the folder with two dots and then we'll have the api and then the post then the same for the hooks we just need to add a dot in front of each one of these so there's two dots and that should be good once we save that we can go back to the app.js and start to grab the rest of this information as well so let's grab all of the state that we have here let's grab the axios fetch the two use effects as well copy all of that control c since i'm on windows and now inside the data provider we can paste that right in just like we had it in our app except now it's in the data provider of course we've left it in the app for now just to keep the application working we can also take all of this logic the handle submit handle edit and handle delete copy that and put it in the context as well now if you have a little bit of experience with react you may be thinking wait what is he doing well right now we're just dumping it all everything that we had in the app.js we're putting in the data context we can get a little more organized later we can think about efficiency some this is a small app react is already very efficient but we'll talk about some of those things here in the future right now just taking all of that stuff we had in app js and we're moving it into our data context and now at the bottom we're not providing anything yet but we will right now we've left everything here as well so let's scroll down in the app.js and the first thing we have is the header you can see the header is receiving a width prop as well as the title we'll leave the title here because you don't have to go all one way or the other you can still pass a prop down like the title while pulling a prop like with from the context so that's what we're going to do back here in the data context we've already defined width above so let's put with right here if we provide more data i'll need to put a comma after that but we already have width defined i believe yes we do right up here on line 19 in the context and so now we're passing it through from the provider and now let's look at the header file in order to use width from the context instead of being passed in as this prop which we can remove from the d structure here let's go ahead and use an import at the top and this will be to pull in use context and that will be as the other hooks from react and then we also need to import our data context that we defined there we go it already helped me out from the context slash data context now that we have those we need to define width since we're no longer pulling it in as a prop above so this will be const and then width and then this will be set equal to use window size oh i'm sorry not use window size that's where we're pulling it from in data context this will be equal to use context and that will be from the data context so if you had more than one context you can see now how you import it and you would pass it in to the used context hook and we want the data context so we pass that in to the use context hook here and we get width it's no longer being passed down but much in the same way we're defining it near the top of our function here just using the use context hood and we can save this and now if we go to the application the width should still be working and we still have an icon there we can go ahead and refresh to see if we have a problem no problem i'm going to open up dev tools and even resize and yes it already resized to a tablet let's go ahead and scroll and it's a phone size it's a tablet size soon there we go and then a laptop yes not going to worry about the warnings right now we've defined many things that aren't being used but we'll continue to switch each component over and will slowly eliminate warnings and errors as they arise okay back to visual studio code i'm going to copy this use context import and data context will need that at the top of every component that uses a context subscription and so now besides the header let's look at app.js we can eliminate this width as well now we want to go to the nav and it receives search and set search so i'll save the app and let's open up the nav file i'll need to paste these two imports at the top same as we had before with the header and then we also want to take a line like this that uses the context and put it into our nav and you'll see a pattern emerge here where we're no longer destructuring as props but we can just put the same props right inside of the used context as we use the hook and so then we can eliminate these props here in the function parentheses okay if we go back to the app.js now we should be able to eliminate search and set search from the nav we can already see how this is cleaning up a little bit now we see home receives posts fetch error and is loading and we also need to pass search and set search in the context if you remember in our data context we had only passed width before so we need to remember to do these as we pass everything along and now we said our next one home is going to receive search results even though we labeled it as posts here it's search results fetch error and is loading so let's set search results fetch error and is loading let's save that much and let's go ahead and pull up the home component okay we'll need to once again copy from header or if you just memorize the imports and type them that will work as well but we've got use context imported and our data context and now also in the header we'll need to use context and pull out what we need from it and again even though this says posts that's because we had labeled it that before it came in so we'll need to switch that to search results if i can highlight it all there we go search results [Music] let's eliminate the props that were being restructured there and now inside of our function we need to change a couple of things because this should no longer be post it would be search results and the feed even though they'll be labeled as posts after it receives the search results as post and we can save that so now we have received all of these with context and we did the same with the nav and we received those here with the context and then of course in our data context we had to provide all of those values here let's go back and see if our application is working it looks like it's working let's do a reload so far don't worry about the warnings of course we've got many things defined right now that aren't being used yet we can still search so everything is working as expected so we're just replacing just a little bit of each component as we go let's go ahead and minimize chrome if we head back to the app.js we can eliminate some more here we have now eliminated all three of these props that were being drilled down to the home component and if you remember some of the components we were able to eliminate all of those and when they didn't have any props being sent to some of the components we were able to just specify inside of the route which component we were routing to like this and so that's much cleaner now let's look at the new post component that receives even more props i'll save i'm going to go ahead and close up the open editors at the top so we have a little more room here and we want to scroll down and choose the new post js you can see it's receiving five different props that are being drilled down so once again i'm going to go to the header file copy these two import lines then go back to the new post and at the top it had no imports before we'll import both of those lines and then we'll take our use context line as well go into the new post paste that in and then take everything that we were receiving as props and we'll receive those from the context and now we'll eliminate what we were deconstructing and save and we should still have all the same functionality because nothing else has changed it's just in how we receive that data let's go back to app.js let's go ahead and remove everything here including the closing route and we'll just use the component and pass in new post and we'll save now let's go to our application and let's go reload once again just to make sure everything should already be fine let's go to new post and let's call this post five oh and you know what we forgot to do we've got an error here set post title is not a function and that is because we didn't take all of those props and send them through the provider yet so this is what we need to make sure we have done handle submit post title set post title post body and set post body go to our data context and make sure all of these are being sent through the provider and once we save we should be able to go back and without error reload the app i'll go back to home and reload the entire thing just to make sure let's have a new post and we'll say post 5 just checking submit and yes we have post 5 just checking so if you get that error just like i did you'll know what is happening you need to make sure you're sending those same pieces of state and maybe even like the handle submit function so maybe even some logic being sent through the data provider if that is how you are providing it to the component let's minimize chrome and we're back here at the data provider now let's go back to app and we'll clean up the next one which is edit post you can see it's receiving probably more than any other component was and so we'll need to make sure we're sending all those same props through the data provider let's go ahead and change this right now to just have a component it says edit post we'll save that which will break the app momentarily let's go to the edit post file and i'm just going to open up nav js this time copy those same two lines go into edit post and i'm noticing at the top i'm already importing use effect from react so i don't really need the separate use context line i can just put use context in the same line there after that i'll go back to the nav again and we're going to go ahead and copy that use context hook line and once we're inside the function here i'll put the use context line i'll cut everything out that was received as a prop and put it into the use context line here eliminate the curly braces from where props were received and save now everything should be okay except we need to make sure all of this is being passed in the data provider as well so we'll put a comma after the set body and we'll paste we'll make sure we don't have any duplicates here we have posts handle edit edit body it looks good so we can save that i believe we've already made the changes in the app.js yes for edit post let's once again go to our application let's pick our new post five let's edit the post and change the five to the word five and just checking in and we'll submit and yes edit post works just fine let's go ahead and minimize chrome not much left to go on this initial refactor but we've got one more component that is receiving some props here our post page so let's scroll down to the post page let's once again copy our import lines context and data context and on the post page we can put those right here now we'll go ahead and copy the use context line for the hook back on the post page again i'll put that right underneath here and then we'll take posts and handle delete and we'll paste those in here and remove the curly braces and now we need to make sure posts and handle delete are already in the data context and if we select data context post was already here but not handle delete so let's go ahead and add that as well and save i'm going to close a file or two at the top just so we can see the ones that we want to have open here's app.js and now we can change this up as well and make it the component close out the route and if we look at our app.js file now it is much much cleaner the data provider surrounds everything and of course we have our routing in here that we previously had including our switch statement but even up above we haven't removed these but we will be able to now because you notice we're not passing any of them down whatsoever there are currently no props being passed other than what we have for our route and we're saying hey this is what the component is so that is much cleaner let's make sure our application is working so we'll reload let's go to post five looks like we can still edit the post i'll remove in here that's good we can delete the post it deleted no problem we should be able to search so if we search for three yes everything in the application seems to be working just fine let's minimize in chrome and now let's go ahead and remove everything that we really don't need in the app.js file i'm going to remove use history as we now have that in the context we won't be using state or use effect or any of the rest of these except the data provider so what we're left with are the components route and switch then from react router and our data provider we're able to remove all of these pieces of state and use effect we should be able to remove all of the different functions we have handle submit handle edit and handle delete and we can save and now our app.js is much much smaller so we're importing in the components the routing and the context and look at this function it is so much smaller and easier to manage than what we previously had as we were drilling all of those props let's once again go to our application reload and make sure it's working but it sure looks like it is and so now we're using context for all of those things let's minimize chrome again and let's talk about how we've organized everything app.js looks much better and our context here has everything that we previously had in that parent component and of course when a parent component renders then so do the children of the components so it was causing lots of re-renders but this still could cause quite a few because everything that subscribes to the context when the context gets updated so would the component so let's think about some of what we're doing and are we actually doing it as effectively and efficiently as we could if we go to app.js and once again look at each component we could stop and think that really the header does not need to receive any of the post data it's only receiving this title prop and then we're passing a width to it if you remember and that determines the icon for the header alone so it doesn't really need to be involved with the rest of this likewise the footer isn't receiving any data either and it doesn't need to be there so we could move our data provider and we could wrap it around everything starting at the nav and ending it at the switch route because that is the area that really needs the post data and so we could save that i'll eliminate these lines here and now that we've done that we need to change the header just a little bit because right now it does depend on that data from the data provider so let's go back to the header and we can go ahead and remove these imports and let's think about how to get the width well it never had to be passed down to begin with so what we could do with the width is just import the window size hook or use window size and that would be from hooks slash and then i believe it's use window size there we go and now that we have that instead of defining width from use context we're just defining it and use window size and that's a very simple change but that totally decoupled the header from all of the data that was involved with the posts and we can go back to the data context and we can say we don't need this use window size import anymore likewise we don't need to define width inside the data context from use window size and finally we don't need to pass it down at all it can just be contained within the component itself the header component can just use that hook and really if we stop and think about some of our other components some of the data that we previously had in a parent does not need to be passed down either so handle delete is probably only going to be on the post page where the delete button is handle edit well that's probably only going to be on the page where the edit is and handle submit probably only on the new post page where we submit a new post so let's go look at the new post page and on the new post page if we stop and think about it this post title and post body along with the set functions is really only linked to this form it has no other role in the application so that could just be state that we keep within this component without sending it to a context because it doesn't need to be shared with other components and really that's what the context would all be about so at the top let's just import use state and let's go back to our data context and we'll copy those lines where we had the post body and post title and we'll just cut those right out of here and we'll go back to the new post and we'll take these and we'll set them at the top and we can eliminate all of the post body and post title that were imported and now the same with handle submit this is the only place that that function is called we might need some other state that is used inside of handle submit but we could easily import that from the context so let's go back and grab that function as well and let's find handle submit here it is we'll take this and just cut it out of our context and we'll take it to the new post component and paste it in and now that we have a handle submit here as well we know we won't need it but i'm not going to get rid of the use context line because handle submit probably has something else we need related to posts everything else is looking good there so now let's go ahead and look at this function clearly it uses posts so we're going to need the posts from context it also has set posts and does it have anything else we'll need no set post title and set post body are now contained within it looks like we're going to need to import the use history from react router though so let's go ahead and do that [Music] import use history from react router dom and then we'll need to define our history to be able to use it we'll set that equal to use history and save and we'll see if our function will continue to work it also has an api call in here so if we're going to use the api we do need to import that into the function as well so we can import api from dot slash api slash posts there we go and save now we have the api in here to make the api call and handle submit as well and everything else looks good so we have our handle submit function and we're containing the state within the component that really doesn't need to be shared and we're pulling in the state that does need to be shared between components and here that is posts let's save this we'll go back to our context and we already removed the function and we already removed the state that we won't be using here but let's go down and what we do need to do is remove the post title post body and everything that we had right here for that because it no longer needs to be passed through the provider if we go back and now look at our application we've got an import which falls outside of the project and that is the use hooks that must be in the header js let's go ahead and fix that import it looks like i have an extra dot in there and let's give this another shot our new post js needs the format import that we also have in context so let's grab that as well put this in the new post component as it's used in the function right here and i missed that now that we've got it let's go ahead and reload the blog seems to be working let's make that fifth post again set posts is not a function which means we did not send that through the context previously if we come back go to our context i believe we sent posts before but we never send set posts let's save go back to our application i'll once again go to home refresh just to be safe new post fifth post again and there is our fifth post and now everything is working as it should and it actually looks like the last one did post so i'll go back and delete it as well and now we're just left with the last fifth post i'm going to minimize chrome and we can look at the next change now that we did that with the new post page let's go ahead and look at the post page as well and say what can be sent here or what could be actually contained in the component that doesn't need to be sent here well posts is something once again needs to be shared amongst all components but handle delete is really only needed in this component that is once again logic that could just stay right here so let's make some room and we'll go to our data context and we'll pull out the handle delete just cut it right out of the context and while we're here we'll go ahead and delete it out of our provider i'll eliminate the comma before it we'll save that and on the post page we should be able to paste it right in but once again the function may need something that we weren't already bringing in so let's take a look oh this is handle edit wait a minute i need to put that back for now and get handle delete here we go i'll just save go back to the post page paste in handle delete and save but what are we missing we are missing the api for sure so we need to import api from dot slash api slash posts and after the api we have set posts coming in no we don't yet so let's go ahead and do that instead of the handle delete that we previously were bringing in from use context and now that we have set posts we're going to need history again from react router dom we already have some from react router dom up there so let's just bring in the history as well we'll need to define history i'll do that right here so we'll say cost history equals use history and now that we have the history we have set posts we have the api i don't think i'm missing anything else but you never know we'll go ahead and save that let's go back to chrome and see if our application is still working we'll try to delete this fifth post i think i'm going to reload first and attempt to delete and the delete continues to work everything is good let's minimize chrome and keep working let's take a look at app js now we have already handled the post page and the new post so what might be logic that would be an edit post that the rest of the application would need let's look at our context and handle edit the function for sure pretty much what we had here handle edit edit body set edit body edit title set edit title those can all just be contained within the component once again because the rest of the application does not need them so we'll just remove those here from the context provider we'll save that let's grab the state first and then we'll come back and get the functions so all of this state right here is no longer needed inside of our context we can just move that inside of edit post and now that we have edit post open we'll put the state right here at the top and we are going to need to still bring in posts and probably set posts so we'll once again pass that right there we've got use effect here with post set edit title set edit body that is fine we're already bringing in use effect here so we need to bring in that function so let's go back and now grab handle edit cut that out of our context as well go ahead and save the context but in edit post we can put the function then right underneath the use effect and save and let's see what else we still need in here we're going to need format again it looks like we'll also need the api and we're going to need history for sure okay so at the top we've already got params and link from react router let's get use history then let's go ahead and define that history as well so we'll say const history equals this history let's import the api import api from dot slash api slash post and save so now we have the api and we still need the format so was that on the post page i don't think so i think it was on new post that we had format there's that import and we'll put this back on the edit post page [Music] and i think we have everything then needed for the handle edit date time updated post so format api history it all looks good let's go ahead and see if the app is working as we expect it to well wait a minute let's see if we eliminated everything from the context yes it looks like we did so let's go back and see if the app is working like we expect it to oh there is a problem use state is not defined we can't forget that at the top of edit post i believe yes we're going to need that right here we brought in all that state and forgot to import use state now that we have used imported maybe everything is going to be working it sure looks like it let's try to edit our fourth post some more testing let's say words press enter and yes it is working with everything now working we can see we're getting a warning that we've got some definitions inside of context that are no longer being used that is because we have paired our contacts down so let's look at the context and say we no longer need the api well this is the edit post let's go to the context there we go we no longer need format or api and do we still have use history inside of here no we are no longer defining history either so we can remove that as well and let's look at the line use history there we go and save so now our context is much smaller than it was the posts and the search are definitely tied into each other because once we receive the posts then we have to set the search results based on what if anything is being searched for so this is pretty much our data that we now have and of course we get a fetch error is loading and we're calling our use axios fetch right here inside the context because it can be called inside of a function like this in react or a react function if you will not a traditional javascript function but we're just grabbing it right here instead of putting that in the home so this is working for us right now and we've contained much of the component logic that's just related to the specific components within those components today we're going to refactor the react.js blog application that we've already created in this series and this refactor will remove the state management from the context api that we did in the last tutorial and we'll move it to easy peasy which is a package that we can install that is built on top of redux it makes using redux easy peasy and so that's a great introduction to using redux and i would actually say using a package like easy peasy or some of the alternatives that they list here on the site instead of using redux directly is really a great choice until you have to use redux directly for possibly an enterprise size application so small to medium applications can certainly use one of these other choices and they list several alternatives here as well as easy peasy and you can see one of the alternatives they list is the context api with hooks in react and that's what we did in the previous tutorial so if you haven't checked that out again refer to that playlist link in the description now let's go ahead and get started with easy peasy okay i've got our blog application open in visual studio code and you can see i've already opened up the package.json file here a couple of things to note one we're going to install easy peasy but the other is we didn't really ever clean this up since we launched it with create react app in the first place and these first three packages we're not using they're testing libraries and we're also not using web vitals so we can clean that up just a little bit with an npm uninstall command and then we can just paste in the title of each one of these and we can remove those from our project if you want to so this is just a quick clean up step here and i'll paste all of these in with the space in between each one and we can remove all of them from our project altogether so the last one being web vitals do that and i'm going to press enter this will quickly uninstall those packages and then we'll install easy peasy all right the uninstall completed and you can see our list of dependencies is now down to what we're actually using in our project so let's go ahead and add easy peasy by typing npm i and then easy dash pz and press enter now that that has completed we can see easy peasy is now listed in our package.json under the dependencies i'm going to go ahead and start json server here by typing npx json-server dash p 3500 for the port dash w and data slash db.json where to look for the data and i'll press enter and this is from a project we had previously worked on in the previous tutorials and so if you didn't already have that installed you want to go back in the tutorial list as well now with that ins in launching actually not just installing we're going to go ahead and launch the react app by typing npm start in a separate terminal window and now when this all gets started we'll be ready to start making the changes to our blog application and now the blog application has launched and really we won't change the functionality today we're just going to refactor to use a different state management approach so i'll minimize chrome for now and we can come back and check the functionality after some changes i'm going to close the terminal windows although everything will continue to run and we need to go ahead and highlight the source folder and inside the source folder in the same level as our index js we're going to create another file and we're just going to call this file store dot js we'll start with an import statement there we need to import create store we also need action funk which will support asynchronous actions and computed which will be computed values of state okay and that's all from easy peasy as you see there we'll also need to import the api because our actions will contain api actions as you'll see we'll pull some of the logic actually back into our easy peasy store and now we'll have export default create store parentheses and curly braces and this is where we'll keep all of our state and actions i'll start the first one here with posts and as you might expect the default state will be the empty array much like we would do in use state and then we'll have set posts and here we'll have an action which receives state and a payload not play but payload there we go and we'll have an arrow function here and this will be state.posts equals the payload that is passed in and i'll save this now after this change i'm going to copy and paste in all of the other state because it's very repetitious and it is the same pieces of state we've used in this blog application for a while i'll just pull that over we need a comma after and paste it all in and here you can see we also have post title set post title post body set post body edit title set edit title edit body set edit body search set search and search results and that is some state that we were keeping in components again that we're pulling back to our easy peasy state store and that is because we're going to have actions as well and now the first thing we will define here will still be state and this is a post count which we haven't had before but easy peasy lets us have computed values and i want to show how that works so we'll pass in state and we'll put an arrow here and then we'll have state dot posts dot length and as you might guess this will tell us how many posts we have now we can also have a get post by id state even though you might think this would be an action it's actually considered state and that is because it won't actually send us the value it's going to send us a function that we define here an anonymous function that is returned we have the arrow and now we'll have state dot posts dot find and then we'll take each post and then we can say host dot id to string like we had previously done in our application strict equals the id now this will also be considered state because it's returning the anonymous function and that anonymous function will then take the id to return the specific post that we want now i'm going to scroll up to get a little bit of room here and then we'll create our thunk actions which are asynchronous actions and the first one will be save post and it will start out with thunk and then we have async and then we pass actions and then whatever the payload is and so we can name it separately but in the documentation you'll see payload here this will be new post as we are saving a new post and then we'll also have helpers and now we have an arrow function after that and the helpers you'll notice we can deconstruct posts from the current state to use inside this thunk action and this is from helpers.getstate and that is what makes that useful oh we need an equal sign there that didn't look right there we go helpers.getstate and now we have our posts now the rest will be the try catch block that we had previously had in the new post js file so let's go there quickly and let's just go to our handle submit function in the new post js file copy the try catch block we're not going to remove it we'll leave this as it is and come back to this file but now we can paste it right in here and just make a few changes our response line will be the same that we'll use the api and will post the new post that is passed in now we don't really need to define this all post variable here we can just take this array that we are creating we'll cut this and replace all posts as we set the posts but now we can't just refer to set posts like this it actually needs to be actions dot set post and then it pulls it from above where we have our state here and our actions and there is set post and so as you might guess the following two both post title and post body need the same so we'll put actions dot in front of those we need to remove the history push remember that is a use history hook that comes from react router and we cannot call hooks inside of our store so that will need to be back in the component after this function save post is called or this thunk action if you will and that essentially completes this thunk action so we can save and now we're ready to put the next and the next one will be delete post and it will start much the same so i'll copy this much paste it here but we can go ahead and change the new post payload it's going to be an id and then of course we need to put the closing curly brace and parentheses as well i'm going to scroll up so we can see this a little better and then we need to go to the post page that has our handle delete function and we can copy and paste the entire try catch block now as we go back to the store and right underneath where we define posts we'll put the try catch we have the api we're passing in an id that is received here once again we don't really need to define post lists like this we can just take the post dot filter that we've defined there cut that replace post list remove that from the code and we need to remove the history once again and leave that inside the component and we can save and now we've completed our delete post thunk action and before we're finished we need to create the edit post thunk action and so we will once again start off like this so we'll copy and paste the thunk we'll have actions now this will not be an id or payload we'll call updated post because it's a post we've edited and updated we once again need to have our closing curly brace and parentheses here so let's now go to edit post js and let's find our handle edit function here it is we will once again copy the try catch blocks and we'll go back to the store to paste those in i'm going to scroll up just a little bit so we can see this better and now we have our updated post being passed in and it is right here we're also referencing an id which we don't have but we can get from the updated post and we could say updated post dot id or we could deconstruct from updated post and that's what i'll do here so updated post delivers the id through deconstruction and then we can continue to reference it like we have in our code now the other thing we need to do is once again add actions dot set posts let's copy this down actions dot set type set edit title and set edit body remove the history and we should now have completed our edit post thunk action now that we've completed the store that we're going to use for easy peasy we can go ahead and apply this to our application and remove the context api and the use context hooks i do want to mention that while we're only using one store you can get more complex with easy peasy and create individual models and pull those into a store as well and you can look at the documentation if you want to make a more complex application with easy peasy let's start adding this to our application by going directly to the index js and now we need to import at the top souls type import and here we're going to import the store provider from easy peasy and then we'll have another import because we need to import the store we just created from dot slash store and now that we have both of those right underneath the react strict mode we want to add the store provider and the store is going to be equal to store and of course it automatically adds the closing one here in visual studio code which we will put underneath the closing router and we can tab in the router and now the store will provide all of our state that we have in the store or the store provider will provide the store state for our entire application so we can save the index.js file and we're ready to move on to the app.js we don't have too many changes to make to the app component we do need to remove the data provider context and we need to remember to remove it down here as well so that data provider that's after the header and then of course it's before the footer the closing one we'll get rid of those and now we need to go to our context and actually move a couple of things back into the app component because we cannot put the hook for our use axios fetch into our data store with the easy peasy so what we need to do is put our request for initial data back in the app component and we were doing that with our use axios fetch hook and the use effect hook to set the post and so then what that means we also need to import use effect and import the use axios fetch hook i'm going to copy this part right here and we'll just type in the rest manually for the imports so we copy these we can scroll back up to where we were and we'll go to app.js and now inside the app we're going to have our use axios fetch and use effect and that means we need to import those so let's go ahead and type import use effect and this is from react and then we also need to import use axios fetch and you can see visual studio code completed that for me it's in the hooks folder and after that we have one other import we need to do and this is from our easy peasy instance so we've got use store actions because we need to pull in set posts and so it's from easy peasy i said instance it's from our easy peasy store and that's what we need to pull in is set posts so we're not quite finished we need to say const set posts and set this equal to use store actions and then it accepts the actions an arrow function and then we say actions dot set posts and now we have imported in set posts from our easy peasy store and we've got our use axios fetch custom hook and notice we're not using fetch error or is loading yet i don't want to send those back to the store oh we need to put set posts in here as a dependency as well okay i don't want to set fetch error or is loading those statuses back to the store those can just be passed down and that is something you can do you can still drill props even though you are using a state management library or solution i should say well here we go or package might be the correct word definitely type something i didn't mean to there now we've got our route and here is our home component and we're going to pass is loading so that equal to is loading and we're also going to pass the fetch error set that equal to fetch air everything else we'll keep in our state management but these well i shouldn't say everything because once we get to a list and we create list items we'll go ahead and drill those props too so occasionally the choice might lend itself towards drilling props instead of state management and you can mix those if you want to looking at the application here we can see the next component that will use any information or data will be the nav component the header isn't really using any so let's go directly to the nav js file and we can see here we're importing use context and data context and we shouldn't need either of those now we will want to import use effect from react and then we'll also need to import use store state and use store actions from easy peasy and now that we have attempted or completed that i believe we've done both we now need to go ahead and pull in some state from easy peasy so let's look at how to do that we were previously pulling in search and set search from the context but we'll need just a little more than that now so we're going to define posts and we'll set this equal to use store state which receives the state and then an arrow and then it is state dot post and we need a little more state so i'm just going to copy this line down and instead of posts this is going to be the search that was previously received and we can just change post select the entire post there we go to search here as well now i'll copy this down again but we need to change just a little more here this is going to be an action that is set search and so instead of use store state this is use store actions and then we need to pass in action so i'll just change both of those instead of search this is set search now we have one more action yet we need in this component and this action is set search results so i'm going to select both of these just go to the end and add results on to the end now we have all of the state and actions that we should need pulled in from easy peasy but we're not using them all yet and we're not using use effect now in our store you might notice we don't have any hooks here in our actions we cannot use hooks in this store but we were in the context so now if i go back to the nav we're going to need to pull our use effect hook in here that was in our data context so let's look at the data context and here is the use effect hook that was helping filter and set our search results so we can copy this go back to the nav js and underneath the state we can paste in the use effect and now here react is going to complain if we don't also put set search results in here as a dependency so let's do that as well for the use effect and now everything is being used that we've imported and i believe we are finished with this component we can see we're using posts here we're using search here as well and we have set search results and below we're using searches the value and we're setting the search here with this controlled form so that is the end of the updates to the nav js and we can move on to the home js component very few changes to make in the home component we can remove the use context and data context imports we do need to import use store state from easy peasy so we'll go ahead and do that easy dash peasy there we go and now we are sending some props down we are sending is loading and fetch error and then we're going to pull in the search results from our data store so we'll just change this use context right here to use store state there we go that accepts the state it has an arrow and then it is state dot search results and we can save that and i believe we are complete with the home component now i'm going to copy this import line because i know i'll need it on the post page and we'll head to the post page component the post page component i'm going to paste the import right over the data context and i know we also need to use store actions it looks like we can change out the use context because we won't need that and we should no longer need the apis that's now in a thunk action so now we've really pared down the imports at the top and let's go ahead and set the state here as well the posts and set posts from use context can be eliminated and now we'll go ahead and set our state underneath we'll change how we get the individual post as well so right now let's define const delete post let's set that equal to use store actions that receives the actions an arrow function and then actions dot delete post and after that we're going to use state and this will be git post by id if you remember that computed state that actually delivers to us an anonymous function that receives the id and that is held with the state so we use store state pass the state and arrow here and then we say state get post by id and now that we have completed both of those we can change how we get the individual post because we already have that logic inside of our easy peasy state so now we just say git post by id and we pass in the id that we are getting from the params above and now in our handle delete function we took the entire try catch block and moved it so we can eliminate all of that but we need to remember to keep our history here at the very end so we can handle delete and when that is complete we will then of course redirect the user to the correct component or page but before that we need to just call delete post and pass in the id that is passed to handle delete and now we can go ahead and save and we should have completed this before we go back to chrome and test our delete function let's go ahead and update the new post page or new post component as well so we'll once again copy these imports and let's go to newpost.js we'll scroll to the top here once again replace the data context import with the imports from easy peasy we should no longer need the api import we should no longer need the use state or use context imports so let's delete that line we'll remove the empty line and now let's look at the state that should be inside the new post component we previously had post title post body and posts all in the component some coming from the context as the posts and then the post title and post body were contained inside the component but we can change that now as it all comes from easy peasy and first we'll define post and we'll set that equal to use store state which will have the state you should be seeing the pattern by now state dot posts from there let's just copy this down so we can use more state and easily replace the word posts and now this will be post title and the next one select both again will be post body and there are the pieces of state now let's get some actions and we need our save post thunk action and that is use store actions which receives the actions and then an error then we have actions dot save post i'm once again going to copy this down and here we'll change save post to set post title we need to change that title back to capital t there we go set title and we'll change the second set of saved posts to set post [Music] body there we go and now we have our store actions as well that are needed it is once again time to look at the handle submit function and see what we have eliminated we moved our entire try catch block so we can remove all of that once again have the history dot push to redirect the user as that could not be inside of our state with easy peasy no hooks allowed there but now we can just call save post and pass in the new post and once we save that our component new post should be complete so let's go back to our application looks like it's still working i'll reload to make sure everything's loaded let's go to an individual post to see the post page that looks like it's working let's go to a new post page and create a fifth post we'll just say checking one two [Music] we have our fifth post if we go back we can delete the post now we're ready to minimize chrome and go back and work on the edit post component so we'll scroll up until we see it in the tree and select edit post scroll up to the top of edit post as well i forgot to copy over the import statement so i don't have to type it but here it is in the post page component just copy this from easy peasy once again need to go back to edit post i'm going to just paste right over the data context import again there we have our use store state and use store actions it looks like we'll be able to eliminate the use state and well we still need the statement though because we need this use effect that is inside of our edit post component so we'll remove use state and we should be able to remove use context and then we can remove the api import as well and our imports should now be complete let's look at the state that we now need inside the edit post component and i'm going to put the id in history at the top and now we can look at this and we need edit title edit body posts plus the associated actions we're also going to be able to need to get the post by id once again so what we can do here to make it a little bit shorter is go to the new post and copy everything we had right here for the state and actions now come back to edit post we know we need the posts edit title and edit body so if we paste all of that in we have the post instead of post title let's just change this to edit title and instead of post body we'll do the same edit body and now we won't need the save post action so we'll change that in just a moment that will need to be edit post i guess so we could change it now [Music] make that edit and then we're going to need set edit title and set edit body so let's select the post actually let's just select the word post and change that to edit that looks great and now that we have the edit post action we can use it below but we also need to be able to get the post by id again and really as i think about it i don't think we'll need the posts on this page at all because we will be getting the post by id so let's eliminate that posts from the state above here that i had and now let's go to the post page and just copy what we already had because it's the same code here we get the post by id from the state we get that anonymous function and then we get the id from it so back in edit post we'll highlight where we were defining the post here and paste in get post by id and then post just like we had on the post page component now we should be able to scroll down and look at our handle edit function as well once again we removed the try catch block so we can do the same here and then we can still use history dot push but now instead of just pushing back where we were which was the home page let's push back to the id page so we look at the individual post to see if we like the changes of that post and if not we could just hit the edit button again so we'll change that history push just a little and now here we need to call the edit post action it's the thunk async action from easy peasy and this will be updated post and if we save that our application should now be working with easy peasy like we expect it to so let's go back and see if i have any errors everything seems to be working i'm going to do a complete refreshing reload okay if we go to testing post can we edit the post it sure looks like it let's put a couple of exclamation marks there and save that looks good let's go ahead and open up the dev tools just to see if we're getting any warnings or if we've overlooked anything form submission cancelled because the form is not connected we may have to look into that but let's see if everything else is working as we expect we'll go to the post here we'll say fifth post testing one two we've made our fifth post let's clear this out again and now let's go back and see if we edit and still get that form warning yes we're still getting the form submission canceled warning i think i know how we can fix that let's go back quickly and scroll down inside of our edit post form and where we have button type submit let's change that to edit type button and if we save this and now we go back to chrome let's clear out the console let's do a fresh reload okay we had changed that post all right here we are fifth post edit post testing one two three and we submit the post is edited we're back to the page no more warning so that is great and we're back to the home let's go back here again delete everything is working in the application like we expect it to let's go back to visual studio code and the only cleanup that we really haven't accomplished yet is to go to our data context and simply delete the file we're no longer using it and so we can also select the context folder and delete that if you want to organize your project a little more you could create a separate folder for your store and models of course you would just have to import to those correctly you could also create a components folder much like we did for the api and hooks i'd recommend that you do not put the index js or the index.css in there but all of the other components could be in a components folder and you will often see that in a project and then of course you would just need to route to those imports correctly as well with that finished i was just thinking about the handle functions that we had created the handle submit handle delete handle edit and while it doesn't really make an impact on how it works we don't need to have the async keyword with those functions anymore so in the post page with handle delete i'm removing the async keyword because remember the thunk in our easy peasy store has the async so we don't need it here for the delete post likewise in the new post component we also don't need async for the handle submit and it again is handled by the save post thunk in our easy peasy store and finally in the edit post component i'll need to scroll up here it looks like in the handle edit function i no longer need the async keyword here either because the thunk in our store for easy peasy has the edit post async handled there so we can save that and with those changes all we're left with is one final change i would like to make to the footer we have been displaying the copyright and the year which is fine but we can do just a little something different and this change will allow us to use our last piece of state well i collapsed that by mistake there we go we need to go ahead and import at the top and this will be use store state and we don't need an action just the state and this will be from easy peasy now that we have that i'm going to remove the today variable that we defined with the date and instead i'm going to define post count if you remember we have that computed value in our store for easy peasy so we can say use store state and once again have the state here with an arrow and then we just say state post count and we're pulling that now from our store i guess we don't even need that blank line that i just inserted and now instead of the copyright let's put in the total post count for our blog and so we still have the paragraph and then in the jsx we'll use curly braces and say post count and then we can say blog post and save and now we should be able to go back to our blog in chrome and see the changes so let's go back and if there we go we have got four blog posts if i make another one of course that i'm referring to the footer i can just say fifth post again and say hey make a fifth post and now it says we have five blog posts down here so that also works as expected and that is managing state with easy peasy and i really recommend you check it out it is a great package that makes using redux so much easier and it really cleans up your application and puts the actions and async actions and even computed values of state in your application in a very easy to manage way okay today we're going to deploy an app to netlify and then we will deploy the same app to github pages so you'll know at least two different places you can host your react development projects we'll start with netlify first and what we have is the package.json file and you can see i've got the 11 tut here this is the tutorial in the series that covered use effect and it was the last tutorial to use local storage instead of json server you wouldn't want to try to deploy json server that is just used as a dev environment rest api you would want to create a real rest api say using the rest of the mern stack for example which would be node and express to go along with react and you could create the back end for those applications like we did the blog application in the series or we also did for the grocery list application this will be the grocery list application using local storage only okay we have the package json here and you can see we check our dependencies and we don't want to take any dependencies to production that we aren't using well we aren't using any of these testing dependencies we also aren't using web vitals so the first thing we'll do is uninstall any dependency we're not using so i'll type npm uninstall and then i can just copy and paste the names of each of these dependencies with a space between each one and that will allow us to remove all of them in just one line of the npm uninstall so i'm pasting in the second one one more testing library to go got it and then the web vitals oh i did not get the t at the end of that one i said event there we go and then web vitals here we'll put a space web vitals and press return and this will uninstall those packages and with the uninstall complete we can now see our dependencies are much smaller and we only have the dependencies that we are using now the next thing we need to do is initialize our git repository at this point i'm going to assume you're familiar with git and have already installed that and have an account on github if for any reason you don't i do have tutorials for getting started with git and github on my youtube channel so to initialize a repository we type git init and after the repository is initialized we want to add all of the files so we'll type git add and a period which will add all of the files unless it's listed in the git ignore file of course and after we do that we need to commit the files so i'll type git commit dash m and here i'm just going to type first commit as the message with that complete we need to go to github and create a new repository so we can push our code to the repository on github so when you're at github if you go to the top right menu you can choose the drop down and choose your repositories and you'll come to this page it has repositories underlined here in red you can see i'm using dark mode just click the new button to create a new repository on github and now we need a repository name so this is going to be our netlify deployment so we'll say react underscore deploy underscore netlify and with that we've already got a public page chosen here or a public application we don't need any of these check boxes because we already have our repository on our computer we're just going to push it to this empty repository on github so we click create repository with the repository on github created we need to come to this line that says or push an existing repository from the command line and we need these three lines of code but we can copy them all at once using this little icon over here to the right so i'll just click that and now we'll go back to vs code in nvs code i'm going to go ahead and expand the terminal window and now that i've expanded it all the way to the top so we have more room i'm in windows i'm going to right click and it pastes all these lines of code into the terminal and it executes everything except this last one and i just need to press enter and it will i guess execute all of them and that's exactly what we need so in a moment when this is complete we'll go back to github and just make sure our code has arrived the process is complete let's minimize vs code and now we're at github again let's click the name of our repo up here react deploy netlify and this takes us to our repository and yes we can see the readme here for the use effect hook tutorial and we've got all of the files here let's check our package json and see if it looks like what we saw in ours and yes we'd already cleaned out the dependencies here they are right here everything looks like we expect it to so with that complete we now need to go to netlify and this would be app.netlify.com [Music] and from there you already have a github account so you can just log in using github if you click that button once you're logged into netlify you will probably see your team page even if it's just your account here it says my get to gray's team i'm going to choose new site from git and once i'm on the create new site page i'm going to choose github you can see you could also do this with get lab or bitbucket i'm going to just choose github right here and this will allow netlify to search my repositories so i can click here where it says search repos and i had react underscore deploy underscore netlify and there it found the repository i'll click the name of the repository and now here's the settings we pretty much need to leave it as is the branch to deploy is the main branch we do not want to add anything to the base directory just leave the default the build command will be npm run build and we want to publish the build directory so it's ready to deploy let's click deploy site we can now see that the site deploy is in progress and down here under production deploys it says building and so this will complete very soon and we will have an address or a link to click to launch our application now the deployment and build is complete and we can click on the link provided by netlify and launch our application and here is our grocery list let's go ahead and add some basic items we've got bread milk and cookies just the essentials of course we can click on a couple of those let's go ahead and reload the application to make sure our local storage is working yes everything came back the way we expected and our application is now live on netlify and here is the address for the application okay we're going to start back at square one to deploy a react app to github pages so you can compare the difference and see if you like to deploy to netlify or to github pages either way works and it's nice to have options okay so starting at square one the first thing we need to do is open a terminal window and once again remove any unnecessary installed dependencies so we'll say npm uninstall and we have the same four dependencies here that we previously did if you went through the netlify portion of this tutorial where we want to remove the testing libraries and then we also want to remove web vitals so copying all three of the testing putting a space between each one and then copying web vitals as well putting that all on the same line and uninstalling those packages and with that complete we can now see our dependencies are cleaned up we're ready to scroll down because we need to add a dev dependency to host on github pages and you can see we have no dev dependencies right now so in the terminal window we'll type npm i just i not i n there we go gh dash pages dash capital d which stands for save dev because this is a dev dependency i'll press enter and this will install and now we can see gh pages has been installed as a dev dependency with that complete let's scroll back up to the top of our package json and underneath the version we need to add home page and a value for home page and the value will be where we plan to have our react application so we'll start with https colon slash slash and then you need to put your github username mine is get da grey and then put dot github dot io and after that put what you plan to name your repository on github i'm going to name this react underscore deploy underscore gh and then quotation and a comma to finish out that now once you've completed that we'll scroll just a little bit and we need to add a couple of scripts to our package json as well the first is a pre-deploy and the value for this pre-deploy will be npm run build and the next is a deploy and the value for this will be g h dash pages dash lowercase d build and with those complete go ahead and save the package json once again notice we do not have a get repository initialized here locally so we need to do that before we can push our code to github or before we can even think about creating a repository on github to push our code to so let's go ahead and type git init to initialize our local repository and after that we're going to type git add and a period to add all the files except those that are listed in the get ignore file and then we'll type git commit dash m and just generic here first commit now you may already have a repository a local repository and that's fine too i just wanted to add this step in the tutorial for those that didn't and now that we have created that local repository we do need to push it to github so let's go to chrome and we have github open but here is the react deploy netlify from the previous variation where we deployed to netlify so let's go to the menu in the top right and choose your repositories and on that page just click the new button to create a new repository and here we need the name that we put in the package json under home page so this is react underscore deploy underscore gh and it says that is available if it's not you would need to go change your package json to something that is available the home page value that is okay and now click create repository and with that quickly finished we need to go to the area that says or push an existing repository from the command line because we do have an existing local repository and we'll need these three lines of code so we click the icon to the right to copy all three let's go back to vs code now in nvs code i'm going to expand the terminal window to the top so we can see everything now in windows i just right click to paste these in i'm not sure what you would do on mac or linux but please feel free to comment below to help us all out now i'm going to press enter and it will go ahead and execute these lines and push our local repository to github and with our code now at github let's go ahead and verify so we're back here let's click react deploy gh at the top the name of the repository and here you can see our local repository has now been pushed to github and that's exactly what we need let's go back to vs code now and let's stay in the terminal and we can type npm run deploy and this will absolutely deploy our react application on github pages when the deployment is complete you should see published in the terminal right after the gh pages dash d build that was issued from our npm run deploy command okay so once we have that we know to go back to the package json i'm going to shrink the terminal and in the package json we already filled in the address where our application should be so let's just copy that and now let's go back to chrome and in chrome we should be able to just paste in that address and see our react application deployed on github pages and here's our grocery list let's add the milk eggs and bacon and let's check off bacon looks good let's refresh the page yes the local storage is working everything about the application is working as we expected it to on github pages okay i'll minimize that because it's a little brighter than the dark mode but now you might want to ask which do i prefer do i like to host my react applications on netlify or github pages well they both have pluses and minuses i will say that netlify involves one more site whereas github pages allows you to host everything directly on github so that's a bonus for github now netlify offers some additional hosting features that i do really like including environment variables and serverless functions so that is also a plus for netlify and overall i don't have to add any extra scripts for netlify like i did here for github pages and i definitely did not have to add a dev dependency like i did for github pages so if you like to just leave your package json alone in addition we didn't even have to provide the home page value for netlify but we did have to do that for github pages so if you like to leave that package json alone netlify may be the choice for you both are great options to freely post your react projects as you're learning react so you can't go wrong either way congratulations on completing the full nine hour react tutorial series to keep improving your newly learned react skills you need to keep building react projects subscribe to my channel for the latest and let's code together again soon thanks for watching
Info
Channel: Dave Gray
Views: 904,481
Rating: undefined out of 5
Keywords: react js full course for beginners, react tutorial for beginners, react full course, react js full course, react full course for beginners, reactjs tutorial for beginners, react js, react tutorial, full course react js, full course react, react complete course, react complete tutorial, react js complete course, react, learn react, react course, react course for beginners, react for beginners, reactjs for beginners, learn react js, react js tutorial, reactjs tutorial, reactjs
Id: RVFAyFWO4go
Channel Id: undefined
Length: 529min 6sec (31746 seconds)
Published: Fri Sep 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.