Importance of Natural Resources

Introduction and Philosophy behind React Router (v4)


In this video, what we’re going to do is we’re
going to look at some of the philosophies behind React Router and we’re also going to
take a look at some of the current syntax. Now, in order to most effectively do that,
what we’re going to do is, is we’re going to take a look at a little bit of the history
of React Router. And where that starts is with static routing. If you’ve used the router from Angular, Ember,
Express, or even a router from before version 4.0 of React Router, you’re probably used
to the idea of static routing. Basically what you do is you declare your
routes before your app ever initializes and then you just tell your app about your routes. So what that looks like is something like
this here. This is React Router before version four,
so we just have our routes here. And then, when we initialize our app or when
we use ReactDOM.render, what we do is we pass our routes to our render function so our app
is basically aware of those. So again, static routing is basically where
we are statically creating our routes up-front and then we just tell our app about those
routes when our app is rendered. Now, this brings up the question, “Is static
routing bad?” Well, it’s not, but it’s not really the React
way of doing things. If you think about the React way, fundamentally
what React is it’s all about components. You’re essentially building your entire UI
by composing components together by component composition. Well, when you declare your routes up-front
using static routing, there’s not really any composition going on there. We basically just have our routes, and then
we tell our app about our routes, and that’s basically it. The mental model for me was always something
like this, where we had our app, our app was full of component, styles, logic, state, basically
everything that made up our app, and then we had our routing. And our routing was necessary in order to
make our app work, but they never really seemed like they flowed together, especially with
React Router. They always seemed like they were kind of
two different things. Even in my brain, I would think about them
two different ways. I would have my app, and then if I wanted
to add routing, I would go and have, like, a routes.js file, and that’s how I would add
routing. It wasn’t really the React way of doing things. And even more than that, if you look at some
of the old React Router syntax again, you’ll notice here that we have this onEnter prop
here being passed into routes. Well, what’s kind of weird about that, is
really what onEnter is doing is it’s recreating componentDidMount. Basically, what we’re doing here is we’re
saying whenever we go to the dashboard component, go ahead and make sure that the user is authenticated. So not only were previous versions of React
Router not really the React way of doing things, because we weren’t really utilizing component
composition, but even worse than that, is because of the limitations of static routing,
it needed to create its own competing API that did basically the same functionalities
that we have built in to React. Now, this is where React Router version four
comes into the picture. The whole goal of React Router v4 was to really
solve all these inconsistencies between the router and the paradigms of React. The goal was to make a router that really
flowed with React. It worked with React rather than fighting
against it. I really like this quote by Mark, he says,
“‘react-router’ has taken on a new meaning. Instead of just being a rather for React,
it’s showing what a truly React router looks like.” What he means by that, is if you already understand
React, you understand the benefits of React, you understand the benefits of component composition,
then React Router v4 is going to feel really nice to you because all of those same benefits
that we get built-in with React are now going to also apply to our router as well. What I’d like to say is that React will make
you a better JavaScript developer, but React Router will make you a better react developer. Well, that’s great. But how does this actually work? Now, this is where dynamic routing comes into
play. We’ve already talked about how static routing
is basically where you define your routes and then you tell your app about those routes
when your app initializes. But with dynamic routing, it’s routing that
takes place as your app is rendering. And really at the heart of that is that all
React Router gives you is components. Everything is a component. So to add routing functionality to your app,
you do the exact same thing as you would to add any other functionality your app, which
is just component composition. And that works because everything with React
Router v4 is just components. So now let’s go ahead and take a look at an
example. What we’re going to do is we are going to
look at this basic example right here which is coming from the React Router docs. So here we have a very basic React component,
which is just for rendering React Router Course, as you can see right here. So, the very first thing we are going to do
is, we are going to import some components that React Router gives us. So first we will import three different things,
Route, Link, and then we will also import this thing called BrowserRouter, but we’re
going to go ahead and a rename it once we import it to just be Router. And all of these things are going to come
from react-router-dom. So make sure you don’t import these from react-router,
instead you import them from react-other-dom because we are using React Router for at the
DOM obviously for the web. So the very first thing we’re going to do
is just create three dummy components. The very first one is going to be a Home component. And all we are going to do here is we are
going to render a

. And then we will render an

element that
just says Home. We are going to have two other components
that look very similar. So I’m just going to copy and paste. The second one is going to be About, and the
third one is going to be the Topics component. So, now what we have, is we have three basic
components here. And what we want to do is we want to basically
render some of these components based on the route that we’re on, which is basically just
React Router if you’ve used any of the previous versions before. So what we’re going to do is we’re going to
come down to our app, and instead of having everything be wrapped in a

what we’re
going to do is we are going to render our router components and then we will have a

inside of this router component. Basically what this router component does
is it’s needed a kind of the root of your application in order for React Router be able
to pass the history or the location of where the route currently is to other nested components
which we’ll see here in a second. So here we have a router, we’re rendering
a

. So let’s go ahead and delete this, and we
are going to render just this little nav bar here. So we have our unordered list, and then inside
of here, we’re going to have some list items. And each list item is going to have a link
component from React Router inside of it. So if you’ve used React Router before, this
should look very familiar to you. What we want to do is we want to have this
link component that when we click on it, it’s just going to take us to our home routes. We want to have this link component, that
when we click on it it’s going to take us to /about. And then we will have this one take us to
/topics. So all these link components are doing is
they are going to render an anchor tag, that when we click on them, will change our route. So now that we have our link set up, let’s
go ahead and actually start creating some components that will show when we get to any
of these routes. So before what we would do is, all of this
logic that we’re about to have right now would go inside of a routes.js file, but because
we’re having or because we’re using dynamic routing with React Router v4, all of these
are just going to go inside of our app. So what we can do is we will render a route
component. We will say when the path matches just / or
the index or homepage, the component we want to render is going to be our Home component
that we created earlier right here. And then we will do that again. We will say when the path matches about, then
the component we want to render is our About components. And then the last when the path matches /topics
the component we want to render is going to be our Topics component. So as you can see here, this should feel pretty
natural to you. What’s going on is when our app renders we
render a router, we render a few links so that we can navigate around our app, and then
we render these things. And what routes do is if the path matches
then the component will get rendered. If it doesn’t, then route is just going to
render null. So if we save this and we look at our app
we have an error. That should be from, as you probably guessed. All right, so now we get our UI here. And you’ll notice that we can toggle these
around. But you’ll also notice one little weird thing
that’s going on here. When we’re at Home, we see Home, but when
we go to About we also see Home and we also see About. The reason for that is because if you think
about what’s going on here, we’re saying whenever the path matches a / go ahead and render Home. Well technically, when we render both of these
components, this first path, it’s still matching because these have a / at the beginning. So what we can do is we can come in here and
give this exact prop to say only render this component if the path matches exactly. So now, you’ll notice that when we are out
About or when we are at Topics we no longer get Home. So this is really the foundation of React
Router. Again, what we’re doing is we’re basically
just rendering components. It feels pretty natural. So let’s take this a little bit farther. You’ll notice that if we look at this basic
example again, we render Home, we render About and then we render Topics. But when we render Topics, what we have is
this nested nav. We have “Please select a topic,” and then
when we select a topic, we get the specific route parameter. So what we need to do is we need to go and
we need to modify Topics to not only render some links but to also change out the content
of itself based on the specific route that we’re on. So basically what we’re doing here, is we’re
doing some nesting with React Router v4. So let’s head up to our topics component right
here. And as I mentioned, instead of just rendering
this

element, what we want to do is we’re going to render a brand new nav. So here we have an unordered list with some
list items in it, and we are going to render three different link components. And if we take a look back at the example
again, you’ll notice…look at this your URL bar when I click on the different links. So you’ll notice that when I click on any
of these links inside of the Topics component, we’re not just going to /rendering, but we’re
going to /topics/rendering. Or basically, whatever the path currently
was, we’re kind of just appending on to that. So heading back over to our code, what we
want to do is we have these three link components again. We want this first one, as we just saw, to
go to /topics/rendering. And what it’s going to say is Rendering with
React. We want the second one to go to /topics/components. And what this link will say is just Components. And then our third one, we want it to take
us to /topics/props-v-state, and we want it to go ahead and say Props v. State. All right, so if we save this and run it,
what we should see is when we click on these you’ll notice that the URL is changing but
we’re not actually rendering anything because we don’t have any route set up to listen or
to render any components of when we are on these URLs. So, let’s go ahead and do that. Now again, with React Router v4 we’re using
dynamic routing. So what we want to do is when our Topics component
renders, which is this component right here, we also want to render a few more routes which
will render some components if the URL matches. So because we have three different links,
let’s go ahead and, for now, we’re going to create three different routes. So the first one is going to be /topics/rendering. And we’ll leave the component blank for now
because we’re going to create that afterwards. The second one is going to be /topics/components. And then the third one is going to be the
exact same thing except it’s going to be at /topic/props-v-state. So now what we need to do is we need to create
a component that’s going to be rendered when the path matches any of these paths. So let’s go up here and we will create a Topic
component, and all this is going to do for now is let’s go ahead render just a

with an

inside that says TOPIC. And then what we can do is we can come down
here, and we can say when the path matches go ahead and render this Topic component. So just to make sure everything is still working,
you’ll notice that when we’re at Home, we get Home, About. Then we go to Topics and now we get these
three links. And then we go to any of these links we get
the word TOPIC here. Now, you’ll notice that things may seem kind
of weird right now. So there’s a few things that we could do to
make our code a little bit better and to show off some of the features of React Router a
little bit more. So the very first thing we’re going to do
is it doesn’t make sense to have three routes for all of these paths because we want to
render the exact same component for each of them. So what we can do is we can get rid of two
of those. We can come in here and we can change this
to be :topicId. And then now, inside of our Topic component,
whatever this is, whether it’s components props-v-state or rendering, that’s going to
come in as a prop inside of our Topic component as topicId. So again what’s happening is when we match
/topic/anything, this topic component is going to be rendered, but it’s going to be rendered
with this match property. And then now let’s go ahead and actually console.log
what match is so we can see this. So now when any of these are rendered, you’ll
notice that we get this match object passed to the component that’s being rendered by
the router, and it has a few different props on it. IsExact, which is basically just saying if
the URL that matches is exactly the same as the path that we’re listening for. Params, you’ll notice that we have topicId,
which is props-v-state. The path which includes the route param here,
and then the full path which is basically just the location up here. So what we want to do is we want to grab this
topicId, and again where this is coming from, is when this component gets rendered we have
topicId essentially as a route param here or as a placeholder for whatever’s coming
after /topic/. And so what we can do is instead of saying
TOPIC we want to go ahead and just say match.params.topicId. So now, when this renders, if we go to Topics
and we go to Rendering with React, you’ll notice that what we are rendering here is
the exact same as the route param up here. All right, so that looks great. Let’s get rid of our console.log here. And there’s a few other places that we can
make our code a little better. Inside of our Topics component, you’ll remember
that we hard-coded all of these URLs here. What if one day we decided to change the URLs
in our website, and instead of being topics, this was something else. It would be kind of annoying because we would
have to go and we would have to change all of these. So what we can do is whenever you’re building
out links like this that are nested, you can also use the match property that React Router
is going to pass the component it’s rendering. And if you remember that match property had
a .url property on it, which was basically the URL that was being built. So what we can do is instead of saying /topics,
we can delete these and replace it with a template string. And then now instead of /topic/ what we can
do is we can come in here and say match.url. And then now, this is going to behave the
exact same, but instead of just hard-coding the URL into our link, what we’re doing is
we’re using React Router’s match.url property. So let’s go ahead to make sure that this is
still working. So you’ll notice the URL is still working. But again, now we aren’t hard-coding that
string. All right, so we’re almost done. The only other thing we need to add to this
example is you’ll notice that under the basic example, when we first come to Topics if we’re
not at any of the child routes, meaning we’re not at /rendering/components, or /props-v-state,
if we’re only at /topics, then what we get is this “Please select a topic.” So what we want to do here is we want to create
a brand new route, that if we’re at topics is going to go ahead and render the text “Please
select a topic.” So, again with dynamic routing, we just render
a route. We say path is going to equal…we could hard-code
/topics or what we can do is use match.url again. So we will say when the path matches the match.url,
then what we want to do is we want to render a specific component. Now, this is a new thing we haven’t talked
about yet. React Router, when you want to specify what’s
going to be rendered when the path matches, you have two options. You can pass in a component if you have a
component you want to be rendered, or if you don’t have a component and you just want to
render something in-line, you can pass in render which takes in a component or a function
as well. And so what we’re going to do here, is we’re
going to have an

. We’ll say “Please select a topic.” And so now when topics gets rendered, we will
render this route which is going to match when the URL looks like that. And we also render this route component that’s
going to match when the path is equal to /topics. And because we don’t have a component that
we want to render, we can just use the routes render property to pass in a function and
say “Please select a topic.” So now if we look at our example, we go to
Home, we go to About, we go to Topics, you’ll notice that we get this right here, and then
we can select these sublinks as well. But you’ll notice that we’re getting the exact
same problem that we had earlier. When we are at /topic/components, we are not
only getting components but we’re also getting “Please select a topic” again. So what we can do, just as we did earlier…I
believe we did that right here…yep, we can come in here and we can say we only want this
path to match if the URL matches exactly. So we just pass in the exact prop and now
when we are at /topics, we get “Please select a topic,” but when we are at any of the child
routes or any of the subroutes, we no longer get that. All right, so that was a very brief introduction
to not only the philosophy behind React Router but also some of the basic examples to get
you started. If this was a lot for you, don’t worry too
much about it. There’s a lot more videos coming after this
one which talks a lot more about React Router, including some of the topics that we talked
about in this video. So again, if you’re a little confused, don’t
worry just keep watching. The videos are eventually going to cover all
of these different examples. So stay tuned.


Reader Comments

  1. You communicate the real advantages of react-router vs old-style static routers. This will most likely be the de facto approach in the years to come. Well done examples! Recommended for every dev out there

  2. This is a great video! I have been learning React for a week now. I first did the two tutorials for React on Codecademy, then I did React for Beginners. Now I am doing Fullstack React, which you co-authored. I wish I would have known about your courses, though, I would have done them instead of the book.

    This video really came in handy. In React for beginners, an early version of React router 4 is used. And instead of exact, it’s exactly.

  3. This is excellent! It really clarifies what they mean by a Route component being almost a stand-in for another React component. Well done.

  4. This is great, thanks, Tyler! But I do have one quibble. The last point you make, on nested URLs, seems to leave an issue hanging. The nested links work fine, but when you click back to /topics, right after clicking on a subtopic (e.g., /topics/rendering), the path reverts to /topics but the content stays the same as /topics/rendering. I sandboxed this and using separate components, the subtopic is removed when you return to to /topics. https://codesandbox.io/s/o9jmj1k226. But another issue arises, which is how to add a <p> element (e.g., "Select a topic") to the /topics path but then not have it also be visible on the /topics/rendering path?

  5. Great Video! Thanks a lot.
    How can I save the state of the selected topic?

    I want to click on "Topics" and select a topic. Now when I switch to "Home" and back again to "Topics", my selected Topic is not longer shown.

  6. This video really helped me grok the philosophy behind 'dynamic' routing vs the traditional static routing. This wasn't clear to me in the docs or projects I was working on and led to a lot of confusion.

  7. Hi. Is the concept of routing introduced to the javascript world through React? Was there client-side routing before the time of JS frameworks? Can we implement routing with vanilla Javascript? If so, can you please make a video about it?

  8. 🚀 Try our new 2019 React Course – https://tylermcginnis.com/courses/react/?s=youtube-react-router-philosophy-introduction

Leave a Reply

Your email address will not be published. Required fields are marked *