Understanding the Basics of Routing in React (pt 1)

Vanessa Martinez
3 min readFeb 15, 2021

When you’re building a React application, you’ll reach a point where you’ll need to create the ability to navigate to other parts of your app. This can be done by 1) clicking on a button, link, image, or some other element on the DOM. OR 2) Changing the URL in the browser.

However, both options require the use of a common routing library, React Router. This library comes with its core library along with two tools: react-router-dom (for web apps) and react-router-native (for mobile apps). For the purposes of this blog, I will be discussing react-router-dom.

Installation

To get started, you can install the library by running:

npm install --save react-router-dom

BrowserRouter

Within the React Router package, you will find the BrowserRouter, which is made for applications with a dynamic server. Recall that “dynamic server” refers to an application with a server that updates. In other words, if your server can update anything in the database (create, update, delete, etc.), then you have a dynamic server. If you’re creating a static application, you’d want to use the HashRouter, but we’ll be discussing the BrowserRouter here.

To set up, you’ll need to give Router, the alias for BrowserRouter, only one child. See below in our index.js file, where the <App /> component is the only child of the Router.

import { BrowserRouter as Router } from 'react-router-dom'ReactDOM.render(  
<Router>
<App />
</Router>, document.getElementById('root')
);

This signals to React that all routing will occur within the <App /> component.

Routes

Next, are the <Route /> components, which will each contain a path pointing to the correct UI. But how does a <Route /> component contain a path? To understand exactly how a route is matched it’s important to take a closer look at what Router gives us.

Router uses the HTML5 history API, which creates a history object, and that history object contains a property called location, which points to its own object. Inside that location object, you’ll find:

{ pathname, search, hash, state }

So, Router knows the current location of the app and when it changes. That’s why we wrap all the other <Route /> components inside the Router, so they have access to the history object, and thereby, the app’s location.

To route to a path, you specify the desired path inside a <Route />.

<Route path='/mushrooms' />

The path is actually a prop that indicates the pathname that the route should match. You can also limit the match using exact, so that it only matches the path and ignores parameters, such as ‘/mushrooms/3’.

<Route exact path='/mushrooms' />

Now that you’ve matched a path, you should specify which component to render. For that, you can use either the component or render props.

Component Prop

After indicating the path, you can use the component prop to specify what should render in the UI.

<Route path=”/mushrooms” component={Mushrooms} />

But this can be limiting if you want to pass props to the component. For example, if I fetch all mushrooms in my <App /> component, I will need to pass down the array of mushrooms in state to my <Mushrooms /> component. For that, we can use the render prop.

Render Prop

If I have an array of mushrooms in state that I’d like to pass down as a prop to another component, I can use:

<Route 
path=”/mushrooms”
render={() => <Mushrooms allMush={this.state.mushrooms}
/>

The render prop takes in a function, which returns a component (or React element) when the app’s location matches the route’s path.

A Quick Word on Switch

If you have a list of <Route /> components, you may find it convenient to only match the first in the list that matches your path. For that, we can use the <Switch /> component, which wraps multiple <Route /> components and matches only the first path that matches the location. This is especially useful if you have nested routes like below:

<Switch>                   <Route 
path='/mushrooms/:id'
render={ (routerProps) => {
const mushId = parseInt(routerProps.match.params.id)
return <MushShowPage {...routerProps} mushId={mushId} />}
}
/>

<Route
path='/mushrooms'
render={ (history) => <MushroomContainer />}
/>

</Switch>

In pt 2, I’ll discuss how to use the <Link /> component to route.

References:

--

--

Vanessa Martinez

Freelance Software Engineer. Experience in JavaScript, React.js, and Ruby on Rails.