React 2021 Advanced Routing - Episode 10

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay welcome to episode 10 of the learning react in 2021 series in this one we're going to be talking about a bunch more things related to routing so last episode episode 9 we were talking about the basics of routing and the link to the github repo with everything is down in the description you'll see that there is a episode for each one of the videos so episode 10 this is the one that we're looking at this time we're building this now last time in the previous videos if you go to the branch before it that was the starting code in this one i've made a bunch of changes because we're going to be talking about a lot of things with this one we're going to be talking about dynamic routing we're going to be talking about using the react router dom hooks we're going to be talking about redirects we're going to talk about where you store state to be most efficient we're going to talk about dealing with empty results and nav links versus links so a whole bunch of different things to talk about in this episode so to speed us along the way i've made a bunch of changes to the code that we were using last time we've removed what was here a component called search history which is over on the side and we had search results last time that we replaced with our main element the main element now takes up this entire space in the middle and then we're going to be loading either home or films or people or planets one of those four components is the way this works right now all right let's jump in to vs code now i've added a markdown file here just to explain two different approaches that we're going to be taking to organizing our components and organizing our state so this is the basic layout for the page we've got our app with header and actually that's the capital h that's our header component from in here then there's a search bar component under that then we've got some html the main element and inside of that there's this main component so main component there's two different ways that we can organize it the first one is inside of here we're going to have this div and then people and person we're going to look at those as if there's two different routes and we'll decide if we want to display one or if we want to display both so there's going to be some decision making that we do right in here and we're going to be looking at dynamic routing to control that the other approach is what i'm doing with the films and planets so this is people in person they're both inside of maine state for people is going to be stored inside of maine the other way we can do this is like i've got people here but just to make this a little bit more reflective we're going to say planets and then inside that is planet so planet is inside of here we have the first level of routing which takes us to planet and then inside of planets that's where we actually get the state and we'll say for planet and this is planet as well to from planets to planet so inside of planets this top level one that's where we're putting the state the data for films and planets is going to be at that top level and then inside of that is the other component nested inside so what's the difference between these two the primary difference is where we're storing that data if we store the data inside of planets films people if the data gets stored there and then there's a child component where we're displaying the details it means every time we unmount planets people or films when we unmount that component we're losing that state data our main component never gets unmounted because it's the container for all these other things so we've got the base layout here and there's our main component you can see there's no routing taking place up at the top level at app.js inside of main if we go there inside of here what we're doing is our basic routing now i've removed the switch statement here and i've removed it because without switch we're no longer bound to a single route if i was to put switch back in here and switch is wrapped around all these other elements films planets people it looks at these different paths and it says as soon as i find one that matches perfectly then it's going to go there and it's going to ignore everything else from that point on so if people was rendered we wouldn't get people slash and then some number you can see here films and planets we've got film is inside of here planets has planet inside of there and we're doing the fetch for the data inside of those components so i'm going to go back to without the switch because we do want two routes people and people slash some number we want both those components to be rendered for these ones the data is fetched at this level inside of main and it's kept here so main never unmounts so we always have the people data with planets and films the data is stored in those components so as soon as you go away from this as long as soon as you're no longer doing this route it means that data is gone all right so let's take a look at films and planets first of all [Music] so films this is what we're going to be looking at we're going to create a state variable called list with use state that's going to hold the list of films we use use effect when the page initially loads this is going to run we fetch the data from the star wars api we fetch that data when it comes back we get the results and then we're going to pass those results through set list which is our function right here and save it so now the data with the json data with the list of films is inside our films.js component down inside the body here you know we're looping through it to write out all of our links and then we're going to add a route that says if we've got the id added on to the end of the films so i've got a route inside of a component that is also inside of a route and you can do this you can have multiple levels of routing this is where film gets loaded and we're passing find film we're passing that function right here find film down into the film component so that the film component can call find film so we're extracting that from props normally what we have up in here is props props right here and then you'd say props dot find film or we can use destructuring right here and just say the only thing in props that i need right now is fine film so i'm grabbing find film and i'm gonna call find film right here so inside inside my use effect which runs after this component loads so after the rendering has been done and i'll come back and talk about this in a minute but after the rendering has been done we're going to call set film with the result of find film we're taking the id for the specific film i'll come back and talk about this this is one of the routing hooks we'll talk about that in a moment but i'm taking the id for the current film passing that back up to films it's going to run through this thing and find the actual object and then that object gets returned to us and saved here as the state and then it will be used to render the page okay in the browser so when i click on films there's a little bit of a delay and then the data gets loaded and written out here when i click on one of these i'm going to be adding the number into the url right now it's just films so there is no film component here yet but the data is stored inside a film list if i navigate away let's say i go to planets you can see there was a delay and then it loaded it i go back to films there's a delay and then i load it every time we go back to the component and it gets remounted the fetch runs again the fetch gets the data and puts it into films i click on here then film gets loaded it finds out what the id was from here we pass that back up to the function in films and say tell me give or give me back the object for the one film that we're dealing with that comes back down here and is set as state so this can re-render and planets is doing the exact same thing i click on the link there's a delay it loads it displays the list i click on one of them that adds to the url this component is then rendered for the first time the id 9 gets passed back up to the function it loops through the data that's stored inside of planets planets finds the one object it's passed back in here set in state and then this can re-render with the actual data from the object okay so planets and films there's always a delay if i'm away from the component and it was unmounted and i come back to it i'll always see that no films no planets there's always that delay now people we've done something different with people inside of people we don't have the fetch here the data is not stored inside of people it's passed down as a prop we're destructuring here to extract props.list so list is inside of props we're destructuring we've got that then inside of our page here's me looking at the prompt and deciding what i want to render so this is one way of conditional rendering we can say look at this property compared to this value if this is true then i'm going to render this thing if it's not true i don't render the second part of this so the pino people this paragraph with no people inside of it is not going to render if the length of the array passed in was anything other than zero if it is then i run this map and i'm going to write out the nav links with all of them i'll come back and i'll talk about link versus nav link in a minute but right now we're just passing in a prop you can see all that i have here is this there's nothing else in my component other than writing out the list i don't have person inside of here i have no fetch inside of here all this does is render either the message or the list back into the browser when i click on here you can see there was a bit of a delay and then it did it so it said no people because there was no data but the data was coming from a prop being passed from maine so no people and then there's the list now the difference here is when i leave and go to films people was unmounted films was rebuilt so i saw the message about no data and then there's the list planets no planets and then the list i go back to people there's not going to be a delay it's just instantly there and that is because the data is stored inside of main it's at the parent level it's above all of this so we have the data at this top level and it doesn't matter how many times i leave and come back because because the main component never gets unmounted it never gets removed from the page it means the data is there to stay now is one better than the other well it looks like yeah going to here i always have to re-fetch i always have to refetch the data i don't have to do that here well it's just it's a question of is the data something that's always going to be static or is there a chance that the data could change if the data could change it's better to fetch it when you render the component when you render the component the data is never going to change or it's extremely rare that it changes okay put it one level up inside that main now the data still has to be someplace where it's accessible to both people and person or films and film it still has to be in a place where both those components can see it but i could go up one more level and store it there if that parent component is something that never unmounts like our main component the main component is the one that has our basic routing all this stuff so i've got people and person both of them are being passed this state value people and that was this fetch so inside of main i've got one fetch that's getting people inside of people there's no more fetch needed i'm just passing the array down [Music] so right here i'm saving it the first time i fetch it and then because main is never removed from my page by any sort of routing this data is there to stay as long as my website is open this is going to be there and i could replicate this i could have one set of data for people one for films and one for planets all up at this top main level then i've got the three arrays that just get passed down as props if they ever do get updated then we get new data automatically passed down to those components but only pass down if they're actually rendered okay so this is dynamic routing the ability to put parameters inside your url so in your route if your path has something that starts with a colon this becomes a variable that is now accessible to you you can go in and get that value and the easiest way to get it is using the hooks now let's use person as an example here we're calling this route and inside of person we're passing down this list but this url is also being passed down there so i'll just save to make sure that's all in there if i come over here and we go into person inside of here i'm going to use the first of the hooks that come with react router dom now there are three of them use params or four of them but i'm going to talk about three of them here use params use location and use history now if you've ever worked with the window.location object or window.history that's what these are these are giving you those objects with parameters that are available to you use params gives you all of those variables the things that we were talking about here in main like id or if there was something else like if there was multiple parts like that i would have id and asdf i would have these two things available as variables i'm going to get rid of that save it again so i have one variable coming through here and it's going to be called id but whatever passes through here that's going to be available inside of params so by importing it from react router dom i can call use params and then let's just write out what's inside of here so console.log params and actually we may as well do all three so let location equal use location let history equal use history so we're going to get all three of these objects and i will give them each a label so p for params l for location h for history we'll change our variables hist and look there we go we save that so these three things when we load person we should see these in the console okay so let's refresh this page and we're in the person details so plh here we go p params it is the object and it's got one property called id and it is the value four when i reload my page i click on one of these other ones we change to 6 now my params is this object with id 6 l location this gives me the path name right here people slash six so that is my url and this path name property inside of here is actually the exact same as if i wrote window.location.pathname h that's my history object and inside of there i've got all of these things i've got methods like push and replace is the same as push state and replace state inside of the actual history object so anything that you need about history location or the parameters being passed through without having to parse them out without having to take this string and then parse it out yourself here i'm getting it with a reference id that's what i've called it so that's all built in there and key is like a hash value representing this url right here so we have all these things available to us i'm going to just comment that one out i'll remove these two because the only one we're using is params right now we'll comment out these two and i will delete those from my code i do not need them so params i'm getting the id and again we could use destructuring if we wanted here as well we could just say i want the id parameter from the params object then i don't have to do this i just i have the id and we could use const here too that's going to work fine so id use params and then i'm using it right here the list that's being passed in i don't have to do use effect wait for the fetch when the fetch is done find this thing so i can put it in state it's being passed through the actual array is held up inside of main.js it's being passed down to me as a prop that i'm extracting right here using destructuring and then i'm looping through it but it's a synchronous operation i'm doing all of this before the rendering takes place and then down here on my page i don't need params anymore i just use the variable id and here i'm doing some more conditional rendering if person exists so this list is being passed down to me i'm checking to make sure person exists because it is possible to get an array but have an id that doesn't exist so what if this was people 642 okay i don't want my page to crash here's the id number that i'm writing just to see it as a reference on my page but it doesn't exist in this array and therefore i don't want anything going wrong here all i'm going to do is say okay if person is a truthy value i want to write out the name if it's truthy write out this so this is a quick and easy way to do conditional rendering inside of your um your components all right so that's it that's the hooks use params use location use history and then we can use those use that data inside of here even if this wasn't directly inside of a route like if i had some other component if there was something else that i had brought in called other inside of other i could also add the hooks i can import use params just like this i could do that inside of other and other would be able to get access to that information as well okay great so there's our dynamic routing um there's the hooks we've done a little bit of conditional rendering link versus nav link let's take a look at that one now we've got inside of people where we're writing this out i've got navlink inside of here we're used to the parameter class name we've used that throughout our react components and if i do this in navlink we're fine i've got my class rendering these things with the orange red color if we go into people.css here's that class name there's the color that's being rendered okay so that's class name nav link really the only difference between nav link and link the biggest difference is the fact that we have the ability to add this active class name is the property that i'm creating and now it understands that the anchor tag that it's generating gets this class name but only if it matches whatever's up here so it's route which is the 2 right here this 2 parameter if that value matches what is written up here then the active class gets applied so if i click on c-3po the two matches the two value in here darth vader the number four people slash four matches the two attribute inside of here so that class is being dynamically added by navlink for us so all that functionality is built in if you use navlink instead of link this is what you get to do up here we could apply the same thing so if i opened up nav here's our links well if i change these all to navlink [Music] but just do that oh we've got to do the import as well import nav link instead of link nothing really changed here but inside of nav css i've got a class name here and i can add the orange red by just coming in and adding active class name is that so if i add that in all three of them they understand if they match there we go people is now red because i'm on the people list if i go to films that's the current one that's the current one so we're getting this functionality in here so in my planets i think i've got [Music] that thing set it's just class name inside of my nav link yeah it's just class name so if i change that to active class name now it will highlight that it matches and you'll note this matches even though there's the number after it so i'm getting both levels matching through that route if i only wanted this one we could add the attribute inside of here exact then it's only going to match an exact match here which means this one would match if there was the 9 and this one would highlight if there wasn't a number after it i don't want that functionality i want both so i'm leaving the exact attribute out of there okay and the last part was the empty results oh no we already have the empty results redirect that was the last part that we needed so redirect what do i do if somebody comes in here and they write gibberish okay these are all rendering and that's absolutely fine but the routing inside of main we didn't have any matches inside of here so what do we do for that let's go back up into app we're loading main so this this and this there's no routing around them all three of those are rendering with that gibberish that we had up in here nothing stopping them from rendering inside of main now i've got routes so i'm saying if we've got this or this or this or this i know what to render if i have an exact match for this i'm going to return this but what do i do if i have a route that doesn't match this that is why we have this redirect this is another tag that we can add we have to import it it comes from the same place as route which is our react router dom right here so i'm going to add that in here we're going to say route and i also want redirect as well as my use location my use location here that the other hook i'm actually using that inside of main i think i mentioned that earlier to get the path name to do the match against people now this is one of my dependencies for my use effect which means if this changes i run this function again we could here at this point say window.location.path name and it does the exact same thing but since i have the variable and i'm using it here as a dependency why not just do this there we go it's working all right back to redirect we have redirect here come down to the bottom and my redirect what i'm going to do is if i got to this point and there was no matches i can come in here and say path or sorry not path 2 to do a redirect where do i want to send somebody to if they get down to this point well in this case what i want to do is i want to send them back to the home now that's a logical place to send it so whatever this path is right here for home that's what i'm going to put inside of here redirect does have some other attributes like you can put it from and okay if you get this thing send them there and that works great if i'm rendering a whole bunch of different things and i want to add this on the end but this really would only work if i knew exactly what the old url was to send them to here i don't i want to build something that's going to handle any one of these situations so they could type anything at all if i got to this point and it didn't match anything this is where i want to send them now one problem i have here is that this needs to be done inside the switch which was the thing that i removed because i wanted to have two routes here that can be handled so i'm going to add the switch in here we're going to go back up to the import i'm going to add my switch inside of there so the switch is back and i'm going to change my fragment into a switch again so now it's going to render one route this or this or this or this so it's going to have to choose between these did it do this and it comes to this one before this one so it's always going to do people and then stop it's not going to do this part unless i take the route and i move it down here now this is inside of this route i'm still rendering two separate components at the same level they're still going to have the same access to that property that i defined inside of main so no problem there and i've turned this into a single match so if it starts with people i'm good this is a decision that it will make after that and this is no longer a one-off now it will do whatever is inside of this route the switch applies to the outer not the inner so switch great home okay wasn't that redirect two okay if i got to this point it means i've made it past all of my valid routes and i'm going to send the person back to here so let's jump back to the browser i'm going to refresh this and here's the home films work yep planets we're good people we're so good i click on films again yeah people i can go to the details for people that still works details for films that still works but if i come up here and i say this route it sends me back to home it does do the redirect for me people there we go still works still works but i was sent back to home because of that redirect and that is dynamic routing and everything else that you probably need to know about routing so we've got those hooks that allow us to get it into the params and the location of history we've got routes with and without switch we've got a redirect that we can use with switch we have nested routing that we're using for films and planets we've got routing at the same level so people and person both being rendered together when we're doing this we've got the state up at the higher level at a place that's not being re-rendered so as soon as maine is rendered for the first time that's when we're going to have access to this data saved up inside of main and if you delve into films and planets and do the state setting inside of there it means every time you're leaving it every time you're unmounting those things you are losing that state data from those components but if it's data that changes frequently that may be exactly what you want to do you want to have the fresh data so up to you which approach you take on that all right if you have any questions about routing feel free to leave those in the comments i answer as many as i have time for and as always thanks for watching
Info
Channel: Steve Griffith - Prof3ssorSt3v3
Views: 1,556
Rating: undefined out of 5
Keywords: MAD9022, web development, JavaScript, JS, CSS, HTML, steve flix, steveflix, web dev, professor Steve, prof3ssorSt3v3, 100daysofcode, MAD9135, react, react js, reactjs, react router, react router dom, router hooks, react router hooks, useParams, useLocation, useHistory, routing with state, react state vs props, fetch with state, useState, useEffect, react router link, react router navlink, react dynamic routes, dynamic routing, react url properties, react url variables, react url params
Id: PNdYfs3cdrg
Channel Id: undefined
Length: 31min 54sec (1914 seconds)
Published: Tue Oct 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.