Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

4.4 Create Nested Routes

Now that we have a router, we can work on displaying an individual deck. So let's start this with the route. Now the way that routes in React-Router work is that we can actually nest the routes, and if the nested route is the one that is being activated currently, then its component will be displayed. But it will actually be displayed within any parent components. Let me show you what I mean by this. So here we're going to create a new route, and the path for this is going to be /deck/:deckId. Now :deckId, of course here, is a token that we can use to refer to whatever the current deck's ID is. And for this, let's display a certain component. The component, we'll call it visible cards. So, here's what's gonna happen. If we go to the home page, we display our App component. And as we've already seen, this is the App component right here. However, what happens when we go to VisibleCards? Well, we're gonna display VisibleCards, but it's going to be displayed inside the App component. So it's important, of course, that the App component have what we already have here, props.children. And you know, we can actually change this a little bit. Let's de-structure within the parameter list here and now let's just grab the children there, and then down here we can just say embed the children. However, either way, this way or the way we just had it, this is gonna work because we have some space here for the children of the app component to be rendered. And so, here when we render visible cards, it will go in as a child of App. Basically, nested routes means nested components. And so it's important that any component, whose route has child routes, is also able to accept child components on its own. Okay, so let's go ahead and create this VisibleCards component. So we're going to create a new file, src/components/VisibleCards.js. Now, we're not actually going to display any cards yet because we don't have a way to make new cards. So, let's just kind of create a dummy component here that will have access to all the parts that we need for when we actually do have cards to display. So, of course, we're gonna start by importing React, right? Because we'll need this when we convert from JSX to actual function calls. So I'll import React from react, and then let's create a constant here that we'll just call Cards. And this is going to be our presentational component. So for now, let's just do something really simple. We'll just have a div here and we'll return Deck will display here. And for now, we don't even have to turn this into a container component, we can just do export default Cards. So now let's go back to App.js, and let's import this. So we'll import VisibleCards from './components/VisibleCards'. Now at this point, we have our new route working. In fact, if we head up to our address bar here and I type in deck/123, you can see that our app displays and we do have the text Deck will display here. That's great, but what we don't have yet is actual links that will take us to our different routes. So if I go through our new deck workflow here, I can't click one yet and be be taken to that deck. And so let's go ahead and add that capability. This is gonna need to be done in a sidebar. And the first thing we're going to need to do is import React-Router's link component. So we'll import Link from react-router. And now, down here in the sidebar, let's see. Right here we have our list items that are displaying the deck name. Instead of just displaying the deck name, let's create a Link element and let's link to, and we can link to /deck/. And actually, what we could do here is use back ticks for ES6's string template feature. We can use ${} to interpolate a value, and we'll just interpolate the value deck.id, excellent. And let's go ahead and close off our Link tag there, and there we go, okay. So now, if we go back to the browser, and let's go to our home page here, I'll create a new deck. We'll say one, I'll create another one, two. And now, I can click on one, and notice our URL has changed. So we have our deck/id, we have Deck will display here. I can click on number two here, and you can see that the URL changes. The content doesn't change, but if you watch the URL, as I switch between the two here, you can see that the last four or five digits of that is changing. Which is great, they have different ideas ID's, and so we can actually switch between those different ID's. Now how can we actually use that ID to get a specific deck? Or to use it in some other way. Now we'll have to do this from within a couple of components. Eventually, we will have to do it from within VisibleCards because we will have cards in the deck. However, right now, let's just keep it simple and do it from within App.js. And we'll do this by converting App.js to a container component. Right now, as you can see, it's just presentational, it just takes some properties and displays them. Let's give it a container component. And in this case, we're only gonna need one function instead of two, and the one we'll need is called mapStateToProps, you remember this. Now, you might remember that it takes a single parameter, props, and from that we can return a specific object. However, now that we're using the React-Router, and more specifically React-Router-Redux, what actually happens here is we get a second parameter here, which is some router information. Now, we don't need the whole router, let's just specifically get the params property. In fact, we don't even want the whole params property, let's de-structure another level here. And from within params, let's just get the deckId. Now, this deckId, remember we have this in our App.js file here. This is the token from within the path params, right? So, here we're basically saying router.params.deckId. And the deckId is actually all we wanna return here, because we're not actually interested in any of the actual state props. So now that we have this deckId, we can use our connect function to create our container component. So let's go ahead and import connect from react-redux. And now, down here where we export App, let's export default connect, and let's pass mapStateToProps. We don't need to pass a second parameter. If we don't, it just won't use that. So we'll mapStateToProps and we'll pass it the App. And now, our app has access to this deckId. So here, as one of the parameters, we can get deckId. And remember, of course, this is not an individual parameter, we're actually de-structuring the props object. But basically, it's another parameter. And so we could actually use this here, we can just throw up an h1 here. Just after our sidebar here, let's throw up an h1, and we'll say Deck, and then we can put in deckId. So now, if we had back to the browser, you can see it's already refreshed, and we have our deck here. Now notice, let's go back to the home page. We have just the word Deck because we don't have an ID. Let's create a new deck here, we can click on that, and we have this deck here. If I go ahead create a second deck and click on it, you can see that the ID changes. Now there's something else you may have just noticed. If we refresh the page here, because our state is currently just held in memory, we don't actually save it. Now, because we have this ID here, it will display here, but that doesn't mean we actually have a deck. Because we can't get a deck from our list of decks. If we looked at our state, obviously our state has no decks because they're not showing up on the side bar. Now eventually, we're going to build a small server backend for this which will store our state on the server. However, in the next lesson, what we'll do is we'll create a tiny little local storage version of our state. And that way, as we build more features that get deeper and deeper into the state, we won't have to start that state from scratch every time our page refreshes. We can store it in local storage until we get those features figured out.

Back to the top