Updated Feb 07 2021
React Router is the de-facto React routing library, and it’s one of the most popular projects built on top of React.
React at its core is a very simple library, and it does not dictate anything about routing.
Routing in a Single Page Application is the way to introduce some features to navigating the app through links, which are expected in normal web applications:
Routing links together your application navigation with the navigation features offered by the browser: the address bar and the navigation buttons.
React Router offers a way to write your code so that it will show certain components of your app only if the route matches what you define.
With npm:
npm install react-router-dom
The 3 components you will interact the most when working with React Router are:
BrowserRouter
, usually aliased as Router
Link
Route
BrowserRouter
wraps all your Route components.
Link
components are used to generate links to your routes
Route
components are responsible for showing - or hiding - the components they contain.
Here’s a simple example of the BrowserRouter component. You import it from react-router-dom, and you use it to wrap all your app:
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'
ReactDOM.render(
<Router>
<div>{/* ... */}</div>
</Router>,
document.getElementById('app')
)
A BrowserRouter component can only have one child element, so we wrap all we’re going to add in a div
element.
The Link component is used to trigger new routes. You import it from react-router-dom
, and you can add the Link components to point at different routes, with the to
attribute:
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Link } from 'react-router-dom'
ReactDOM.render(
<Router>
<div>
<aside>
<Link to="/dashboard">Dashboard</Link>
<Link to="/about">About</Link>
</aside>
{/* ... */}
</div>
</Router>,
document.getElementById('app')
)
Now let’s add the Route component in the above snippet to make things actually work as we want:
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Link, Route } from 'react-router-dom'
const Dashboard = () => (
<div>
<h2>Dashboard</h2>
...
</div>
)
const About = () => (
<div>
<h2>About</h2>
...
</div>
)
ReactDOM.render(
<Router>
<div>
<aside>
<Link to="/">Dashboard</Link>
<Link to="/about">About</Link>
</aside>
<main>
<Route exact path="/" component={Dashboard} />
<Route path="/about" component={About} />
</main>
</div>
</Router>,
document.getElementById('app')
)
Check this example on Glitch: https://glitch.com/edit/#!/flaviocopes-react-router-v4/
When the route matches /
, the application shows the Dashboard component.
When the route is changed by clicking the “About” link to /about
, the Dashboard component is removed and the About component is inserted in the DOM.
Notice the exact
attribute. Without this, path="/"
would also match /about
, since /
is contained in the route.
Inside the rendered component we can see which route we are on, using the useLocation
hook:
import { useLocation } from 'react-router-dom'
//...
function Post() {
const location = useLocation()
console.log(location.pathname) // '/'
}
Inside the rendered component you can programmatically change the route using the useHistory
hook:
import { useHistory } from 'react-router-dom'
//...
function Post() {
const history = useHistory()
history.push('/post/new')
}
You can have a route respond to multiple paths using a regex, because path
can be a regular expressions string:
<Route path="/(about|who)/" component={Dashboard} />
Instead of specifying a component
property on Route
, you can also set a render
prop:
<Route
path="/(about|who)/"
render={() => (
<div>
<h2>About</h2>
...
</div>
)}
/>
See how to get data from a dynamic React Router route.
I wrote an entire book on this topic 👇
© 2023 Flavio Copes
using
Notion to Site.
Follow on Twitter
Solopreneur? Wannabe? Adventure awaits