An Introduction To React Router - Routing Basics
React
04/06/2019
A nice perk of React being solely a library, as opposed to a complete JavaScript framework, is its learning curve. Unlike Angular, you aren't required to learn about a bunch of new concepts in order to use it. However, once your app starts growing in size, you'll soon realise that you need to import other functionalities from beyond the library itself. Naturally, this brings us to routing, particularly an introduction to React Router 4.
Routing in Single Page Applications
Before we start getting technical, let's first answer the question "What is routing?". However, if you're already familiar with this concept, feel free to skip ahead. 😉
In a traditional Multi Page Application (MPA) like Wikipedia, whenever you want to access another part of a website, you simply request a different HTML file from the backend server. You carry out this request through the address bar in your web browser. Imagine you want to access my Wikipedia page at https://en.wikipedia.org/wiki/dilshan-kelsen
(doesn't exist... yet!). Accordingly, you would receive a rendered HTML file of that page which is then displayed in your browser.
But this isn't how Single Page Applications (SPA) work. Ohhhh no! I mean, how could they? You only have a single HTML file available from which the entire website is rendered. Instead, they way you navigate through a SPA is by swapping out components that are displayed on your screen. For example, imagine a HomePage
component being swapped with an AboutUs
component when clicking on About Us in the navigation bar. In a similar fashion as before, we tell our router what components we want to display by submitting information through the address bar. However, we actually never ⚠️ make a GET request to the server! Rather, we send this information to the router in our application.
Confused about Multi Page and Single Page Applications? Check out my article them to learn the difference!
React Router
As you might have guessed, React Router (RR) will act as the routing system of your React application. Doesn't take a genius to figure that out... 😬
Preparation and installation
I believe software development is best learnt through hands-on experience. Naturally, you can follow along using your own React project or you can simply create a new one with npx create-react-app <app-name>
. And don't worry! npx
is automatically equipped with npm 5.2 and higher, so you won't need to install anything else. Furthermore, you also want to have two or more components ready to fiddle with so we can practice some routing.
Following along with a newly created project? Here's some sample code that you can copy into your App.js file. Make sure to actually include these components into your App
component with <HomePage />
and <AboutUs />
.
// To include in App.js
function HomePage() { return ( <div>Welcome to this fairly empty homepage!</div> );}
function AboutUs() { return ( <div>Howdy! This is the about page of the fairly empty website.</div> );}
Furthermore, depending on the initial design of your Create React App, you may also want to activate your artistic abilities and change some CSS, such as the background colour and minimum height, in order to see your components. 👨🎨
Moving on! To actually install RR, you want to run the command line npm i react-router-dom
. Next, we will focus on three main components: <BrowserRouter>
, <Route>
and <Link>
. I will get into these next. 👇
BrowserRouter
RR has two main routers: BrowserRouter
and HashRouter
. You can imagine these as two separate systems for how your routing is managed. And which one should you use? Well, generally the former should be used for SPAs and the latter for MPAs in which you added a React application with routing functionality. This distinction is important since the routing of your backend server and that of RR can sometimes interfere with each other and cause some unexpected surprises.
For a better understanding of their differences, I recommend watching a YouTube video by RailCoding. Keep in mind that it contains an older version of React Router, so the names and code might look a bit different. However, the principle behind it remains very much the same. In this tutorial, I will be focusing on the former since most of you reading this will be developing SPAs (Right? 😅).
Now, in order for our application to make use of any routing functionality from RR, we need to wrap the entire application in a <BrowserRouter>
tag. We can do this either in the index.js file...
// Don't forget to import BrowserRouterimport { BrowserRouter } from "react-router-dom";
ReactDOM.render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));
...or the other alternative would be to use it inside our App
component in App.js. The choice is yours!
// Don't forget to import BrowserRouterimport { BrowserRouter } from "react-router-dom";
function App() { return ( <BrowserRouter> <div className="App"> ... </div> </BrowserRouter> );}
Route
The next component we're looking at is <Route>
. This is essentially where your desired component will be rendered according to what is specified in the address bar. Take the example below for instance.
// Don't forget to import Routeimport { Route } from "react-router-dom";
<Route exact path="/" component={HomePage} /> // HomePage is rendered here<Route path="/about" component={AboutUs} /> // AboutUs is rendered here
<HomePage /> // No longer needed<AboutUs /> // No longer needed
Here, we specify two routes: /
and /about
. Whenever the first path is entered into the address bar, our <HomePage>
component is rendered wherever the <Route>
component is located. Similarly, when /about
is entered, <AboutUs>
is rendered. You may have also noticed that the first route has the attribute exact
in it. Why's that? As the name implies, this is to make sure that RR renders the desired component only when the exact path is found in the address bar, rather than in a subset of the URL. For instance, if we were not to use it, even if we accessed <AboutUs>
with /about
, it would render <HomePage>
as well since it found /
in /about
. Got it? 🧐
Now, technically you can place <Route>
wherever you want in your application. However, it makes most sense to group them together as seen above.
Link
Alright, so we can access different components by typing different paths into the address bar. But as you probably learned in Web Development 101, no one navigates a website like that. Instead, we use internal links. And <Link>
serves this purpose. Now, instead of passing an href
, as we would to with an anchor tag, we pass in the props to
with a path of our choice.
// Don't forget to import Linkimport { Route, Link } from "react-router-dom";
<Link to="/">Home</Link><Link to="/about">About</Link>
In addition, we can also make use of <NavLink>
. It acts pretty much the same as its other counterpart, except that it styles itself as “active” when its to
prop matches the current location.
Handy tricks
Now, using what you've learned so far in this tutorial, you could last quite a while until you need to open up the documentation for further details. However, before I let you go, there are a two more handy tricks 🤓 that you might make use of when routing!
Redirecting users
You can redirect users on your site using the <Redirect>
with a to
props, as seen in <Link>
. For instance, imagine a situation where a user clicks a button that triggers a function that in turn returns this component, thus redirecting the user.
Passing down props to children
Developers like to emphasise, oh so often, that your code should be DRY (Don't repeat yourself). Hence, the purpose of reusable components. Moreover, imagine reusing a component with slightly different props in various situations, i.e. depending which path you're on.
<Route path="/" render={() => <HomePage someProps={'Chunk Bytes'} />} />