This course has been updated! We now recommend you take the Complete Intro to React, v7 course.
Transcript from the "URL Parameters" Lesson
>> Brian Holt: So we're gonna get going, we're gonna create another route. So let's create a new file here, call it Details.jsx.
>> Brian Holt: Oops, and we're gonna put that inside of JS.
>> Brian Holt: One thing I was gonna mention is that we haven't written tests for details or showCard or any of our other components.
[00:00:22] You would, right, you typically would write tests for every single component, if you're gonna write tests at all for those. We're not going to because it would be redundant, right. I wouldn't be showing you new concepts, which is kind of the point of what we're doing here. So, for now we're only gonna be writing tests for Search, and then eventually we'll write more tests for Redux.
[00:00:40] But we're not gonna write the other rest of tests, but you should, right? In fact, it might even be a good exercise for you to understand how to write tests. Okay, so we have details. First thing, since we're already typed everywhere else we're gonna first thing opt into typing.
>> Brian Holt: import React from 'react' and we're just gonna make a bare bones const Details =,
>> Brian Holt: We're gonna have div className = 'details',
>> Brian Holt: And you can put an h1 in here with, hi lol, whatever you wanna put in there. Just kinda make sure everything's gonna work first before we work too much on it.
[00:01:35] export default Details, okay. So now we have a bare bones of component.
>> Brian Holt: And then we're going to go import that into our router and make use of that. So go to app.jsx, sorry, app.jsx not Kleiner. We're going to import,
>> Brian Holt: Details from ./Details. And we're going to make a new route here, which is gonna be Route path=/details/:id, and component is going to be equal to Details.
>> Brian Holt: So what this is saying is we're gonna make a details page for each individual show that we have, right?
>> Brian Holt: And we wanna be able to address each show individually, right. So we're gonna have details /:id, right? So that :id is going to be the imdbID for that particular element.
[00:02:48] And then if it matches that it's going to call the details route and it's going to pass this id into details as well.
>> Brian Holt: Cool.
>> Brian Holt: So what we're going to do here is we're going to first check to make sure that it works.
>> Brian Holt: My notes are incorrect here so if you're following my notes, just be aware that I need to fix that.
[00:03:22] So we're gonna go here into our page.
>> Brian Holt: And it's not running right now, so we're going to get it running first.
>> Brian Holt: yarn dev,
>> Brian Holt: Okay, and then we're gonna come in here to this page. Okay, and then just to make sure everything works, we're just going to write a URL that would match that route.
[00:03:47] So, /details/something, right? It could be literally anything. And notice that we get this hi lol, right? So, it's working, right?
>> Brian Holt: In fact, something that we can do here so you can see what that looks like, we come in here to Details really quick. If you want to see what those parameters the routes passing in, we can do <pre><code> and then do a JSON.stringify.
[00:04:18] We've done this before so hopefully this looks familiar, to props, null, 4,
>> Brian Holt: And we're gonna pass in props here. So the first thing, it's gonna yell at us and say hey, I don't know what those types are. That's fine, I don't care yet.
>> Brian Holt: I'm more interested in just seeing what it looks like.
[00:04:41] So you can see here, this is probably kind of hard to see but let's make it a little bit bigger.
>> Brian Holt: So notice that we get something of a match, right. So we can see what information is coming from the match, right? So this is the path that it matched, the exact URL if there was an exact match and the params that came in, right?
[00:05:03] So I called this URL with /detail /1, right? If I call this with something-else, it's gonna come in with something else as that ID, right? So that's going to be pulled from the URL for you.
>> Brian Holt: You can see the location, that's being passed in as well as well as the history object.
[00:05:25] And this is going to be literary the history package from MPM. That's how React Router DOM works, is it works with this package called history and so you're able to manipulate the history that way as well.
>> Brian Holt: Okay, so let's go ahead and actually do something with it now.
>> Brian Holt: So we'll drop this right here cuz we don't need it.
>> Brian Holt: And,
>> Brian Holt: Yeah, I showed you that.
>> Brian Holt: Actually, what we're gonna do first, there's a couple strategies that we could employ here to get the correct data into the details page, right? So we're reading stuff out of this props, or it's not props, but data.json, right?
[00:06:24] And for a details page, it's concentrating on one show right, it's not concentrating on all of the shows, it's just one. So one thing that we could do is inside of the details page is just given that parameter id, we can go and find the correct show out of our data.json.
[00:06:40] I don't think that's the best approach. I think the details page should be unaware that other shows that even exist, right? It should just have the one show and that'll make it more flexible. That way the details, the particular show can from any number of sources, right? It can come from API, it can come from a hydrated server side rendering data store, it could be siloed in some other way, right?
[00:07:03] It makes it more flexible as well as more testable. So what we're gonna do instead is we're gonna go to app.jsx. And what we're gonna do up here is we're going to import the data up here.
>> Brian Holt: preload from '../data.json', okay?
>> Brian Holt: Now we wanna pass the correct show from preload into Details, right?
[00:07:37] However, notice that we're not actually rendering, we're not creating an instance of details right here. We're just passing at the general component and then Route is rendering the component, right? So how do we pass props from what we have inside of app into details?
>> Brian Holt: Well, there's kind of a cool trick you can do here.
[00:08:00] If you have a function that returns a component, that in and of itself is a component, right? Cuz you can have these functions, right, in fact, this one's perfect. This is a perfect example right here, this is a function that returns markup, right? So here, we could have a function that returns details
>> Brian Holt: And that also works, right? Because now, this in and of itself, this block right here is another component. What's cool about this, is now we can pass things into details, right? We can pass props into details. So, stuff='cool', right? I don't know, whatever you wanna put in there.
>> Brian Holt: But now what we can do instead, we can say show =,
>> Brian Holt: And then we can figure out which particular show we wanna pass into there. So we can do preload.shows.find I think is the method I wanna use. So I'm gonna do find,
>> Brian Holt: And this is gonna be a show, and it's gonna be props.params.id === show.imdbID.
>> Brian Holt: So we have a couple of problems here. Well, first of all, this is actually going to work. So, now if we save this,
>> Brian Holt: We have some complaining from our type system but we're going to figure that out real quick.
>> Speaker 2: Does that arrow function have to accept props?
>> Brian Holt: Yeah, exactly, thank you.
>> Brian Holt: So it's gonna be mad that this isn't typed either. But we'll placate the type system momentarily.
>> Brian Holt: In fact, you'll kinda see this pattern emerging of how I write flow. It's like, I'll just write whatever the hell I wanna write, then I'll go back and figure out the types, right?
>> Brian Holt: So something else is not actually a valid ID, right?
[00:10:34] But, if I put in something like one of these,
>> Brian Holt: Did I break it? I broke it, didn't I?
>> Brian Holt: But anyway, what I'm gonna be pulling out, if you look here in your data.json. You can just pick anyone of these imdbIDs right here. So let's look at, I don't know.
[00:11:06] How about Stranger Things? We'll pull that one off, come in here and paste that in here, see what is going on.
>> Brian Holt: Cannot read ID. So let's go and figure out why it can't read the ID. So going back to the app.jsx,
>> Brian Holt: So component here, props which is gonna return a details parameter, preload.shows.find(show,
>> Brian Holt: This should refer to that prop, props.params.id, which will probably equal to show.imdbID.
>> Brian Holt: Let's make this a little bit more,
>> Brian Holt: Little less clever.
>> Brian Holt: Okay, and then we're gonna set, we'll pull this out here just a sec.
>> Brian Holt: Const selectedShow = that.
>> Brian Holt: And we'll pass in our selectedShow right there.
>> Brian Holt: Okay,
>> Brian Holt: Still getting an error there, so props,
>> Brian Holt: .params, so I guess let's just console.log(props) here.
>> Brian Holt: Cannot read ID there. Well, that's not super useful.
>> Brian Holt: So for now we'll just comment that out cuz I'm sure that's where it is, and return an h1.
>> Brian Holt: Let's see what's going on.
>> Brian Holt: Okay, so that's all fine I think.
>> Brian Holt: So is she getting from, it's from match.
>> Brian Holt: See, okay. So this is something that my type checker was trying to tell me, and I was just ignoring. [LAUGH] So it should be prop. So if we go back down here,
>> Brian Holt: It should be props.match.params.ID.
>> Brian Holt: And if we come back in here, and get rid of this h1 right here.
>> Brian Holt: There you go, and now notice that show is actually being passed down into details, right?
>> Brian Holt: Okay, so let's recap cuz there's a lot that went on there.
[00:14:55] So what we put in here was this is a component here that it's going to select the correct show and then it's gonna pass that show down into details. Now notice that we lost the match detail, the history, all that stuff that was being passed down to details.
[00:15:17] And that's kind of a problem. You want those things to still show up because details is a route and it should have access to that data. So what we're gonna do here after show is just put in hey, just give it the rest of the props as well.
>> Brian Holt: That's just good practice that if it's a route it should get all that detail. So now if you go back here and refresh,
>> Brian Holt: So the reason why it's not actually refreshing right now for us is because it's encountering errors, and it will only refresh when there are no errors.
[00:15:50] That's why hot module reload is not firing right now. But now notice it's getting the show, the match, the location, the history, and all that kind of stuff, cool?
>> Brian Holt: So let's actually go and fix some of our types here because this is saying, hey, you're accessing Match and I can't validate that that's gonna cause an error, so please help me understand what's happening here.
>> Brian Holt: Well, what's cool is match is actually a type that React Router DOM exports for you. So we can actually just pull in Match. So we're gonna come up here and say, and this is specific to flow right now. You're gonna import type Match,
>> Brian Holt: from 'react-router-dom'. This came from flow typed.
[00:16:48] Okay, so now we have this Match type and we can tell this props right here that it's gonna have a Match and that match is going to be a Match.
>> Brian Holt: That make sense? So props is gonna be an object on that, it's going to have a match object, which is going to be of type Match.
>> Brian Holt: So this match corresponds to that, right? And that capital M Match corresponds to that match right there. It's a little confusing when things are called the same thing, but that's what's happening.
>> Brian Holt: Now let's talk about that we're accessing this object called params, right? Params is going to be defined by definition on Match, or else something else is gonna throw a flow type error.
[00:17:42] So we know for a fact that match always come with params. And then everything else on params is anyone's bet, right? But flow type's not gonna validate that for you.
>> Brian Holt: I don't think, I think if I put other here.
>> Brian Holt: No, it's not, it's not smart enough to know that ID is gonna be from this, right?
[00:18:03] It's not gonna do string interpolation for you, sorry.
>> Brian Holt: So what match is going to be, is it's gonna be an object of anything. And it's just not gonna validate anything that's coming back from params.