The React Router Cheatsheet – Everything You Need to Know
React Router is the de facto routing library for React web applications. If you‘re building anything beyond the most basic React app, you‘ll almost certainly need to implement client-side routing to navigate between different pages and display the appropriate components.
That‘s where React Router comes in. While there are a few different flavors of React Router (for web, native, etc.), we‘ll be focusing on React Router DOM (react-router-dom) which is designed for building web applications.
In this comprehensive guide, we‘ll cover everything you need to know to master React Router and use it effectively in your projects. We‘ll start with the basics of installation and setup, then dive into the core components, hooks, and techniques you need to define routes, create links, redirect users, handle URL parameters, and much more.
Whether you‘re new to React Router or have some experience with it already, this guide will serve as your go-to reference and cheatsheet. We‘ll provide plenty of code examples along the way. Let‘s get started!
Installing and Setting Up React Router
The first step to using React Router is to install the react-router-dom package using npm or yarn:
npm install react-router-dom
Once it‘s installed, you‘ll need to import the BrowserRouter
component (typically aliased as just Router
for brevity) and wrap your entire application inside of it. This is usually done in the top-level App component:
import { BrowserRouter as Router } from ‘react-router-dom‘;
function App() {
return (
<Router>
{/* Application code goes here */}
</Router>
);
}
By wrapping your component tree in BrowserRouter
, you enable React Router functionality throughout your app. Any router-specific components and hooks can now be used. With this basic setup complete, you‘re ready to start defining routes.
Defining Routes with the Route Component
The heart of React Router is the Route
component. It‘s used to map URL paths to components. Whenever the location changes, Route
will automatically render the appropriate component based on the URL.
Here‘s a basic example of defining two routes – one for the home page ("/") and one for the about page ("/about"):
import { Route } from ‘react-router-dom‘;
function App() {
return (
<Router>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Router>
);
}
The path
prop specifies the URL path to match, while the component
prop specifies the component to render when that path is matched. The exact
prop ensures that the path must match exactly, otherwise "/about" would also match the "/" route.
Instead of the component
prop, you can also use the render
prop to inline the rendered JSX or perform some conditional logic:
<Route path="/dashboard" render={() => (
isAuthenticated ? <Dashboard /> : <Redirect to="/login" />
)} />
Routes can also directly render child elements:
<Route path="/about">
<About />
</Route>
Rendering Multiple Routes with Switch
When you define multiple Route
components inside a Router
, you may notice some strange behavior – multiple routes can match and render at the same time.
For example, if you have both a home page route ("/") and an about page route ("/about"), navigating to "/about" would render both the home page component and the about page component.
To fix this, you can either mark the more specific route as exact
, or wrap your Route
s in a Switch
component:
import { Switch, Route } from ‘react-router-dom‘;
function App() {
return (
<Router>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/contact/:id">
<Contact />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
The Switch
component will only render the first child Route
that matches the current location. This ensures that only one page is rendered at a time.
It‘s important to note that Switch
components match routes based on the order they are defined in. So more specific routes (like "/contact/:id") should be placed before less specific or catch-all routes.
Handling Invalid URLs and 404 Pages
If a user navigates to a URL that doesn‘t match any of your defined routes, you‘ll likely want to show a "404 – Page Not Found" message rather than a blank screen.
To do this, you can define a catch-all route that matches all paths by using the path="*"
prop:
<Switch>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="*" component={NotFound} />
</Switch>
Now if the user goes to any path not defined like "/xyz", the NotFound
component will be rendered.
Navigating with Link and NavLink
Of course, we don‘t want to make our users manually type in URLs to navigate around our app. React Router provides two components for creating links: Link
and NavLink
.
The Link
component is used to create a basic link to a location:
import { Link } from ‘react-router-dom‘;
function Navigation() {
return (
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
);
}
The "to" prop specifies the target URL or path to navigate to when the link is clicked. The Link
component will render an <a>
element in the DOM.
Often, you‘ll want to style the active link differently to indicate the current page to the user. That‘s where the NavLink
component comes in:
<NavLink to="/" activeClassName="active-link">
Home
</NavLink>
The activeClassName
prop lets you specify a CSS class to apply when the link‘s to
prop matches the current URL. You can also inline styles with the activeStyle
prop:
<NavLink
to="/about"
activeStyle={{
color: ‘red‘,
fontWeight: ‘bold‘
}}
>
About
</NavLink>
By combining Link
and NavLink
, you can create a navigation menu that lets users navigate between routes and visually indicates the current page.
Redirecting with the Redirect Component
Sometimes you‘ll want to automatically redirect the user from one route to another, such as after they successfully log in or if they try to access a protected page without being authenticated.
The Redirect
component is perfect for these use cases:
import { Route, Redirect } from ‘react-router-dom‘;
<Route path="/private" render={() => (
isAuthenticated ? (
<PrivateComponent />
) : (
<Redirect to="/login" />
)
)}/>
Here, if the user is authenticated, the PrivateComponent
is rendered. If not, the user is redirected to the "/login" path.
You can also use Redirect
outside of a Route
for more general-purpose redirects:
function UserProfile() {
if (!user) {
return <Redirect to="/" />;
}
return (
<div>
Welcome {user.name}!
</div>
);
}
Hooks in React Router
React Router provides several hooks that let you access the state of the router and perform navigation from within your components.
The useHistory
hook gives you access to the history
instance, which you can use to navigate programmatically:
import { useHistory } from ‘react-router-dom‘;
function BackButton() {
let history = useHistory();
return (
<button onClick={() => history.goBack()}>
Go Back
</button>
);
}
The useLocation
hook returns the current location
object, which contains information about the current URL:
import { useLocation } from ‘react-router-dom‘;
function CurrentPath() {
let location = useLocation();
return <div>Current path: {location.pathname}</div>;
}
The useParams
hook lets you access the parameters of the current route. For example, if you have a route like "/users/:id", you can access the "id" parameter like so:
import { useParams } from ‘react-router-dom‘;
function UserProfile() {
let { id } = useParams();
return <div>User ID: {id}</div>;
}
Finally, the useRouteMatch
hook lets you check if the current URL matches a specific path:
import { useRouteMatch } from ‘react-router-dom‘;
function SomeComponent() {
let match = useRouteMatch(‘/blog/:slug‘);
if (match) {
return <div>The blog slug is: {match.params.slug}</div>;
}
return null;
}
These are just some of the core hooks available in React Router. They give you a lot of flexibility and power when it comes to accessing route data and navigating programmatically.
Advanced Topics
As your application grows in complexity, you may need to employ some more advanced techniques with React Router.
Nested Routes
Nested routes let you render components within other components that are already associated with a route. The match
object passed as a prop to route components contains a path
and url
property that facilitate building nested routes.
Code Splitting
Code splitting lets you split your app into multiple bundles which can then be loaded on demand or in parallel. React Router is built with code splitting in mind and provides utilities to make this easier.
Animated Transitions
React Router doesn‘t come with built-in support for animated transitions between routes, but it‘s relatively straightforward to roll your own using libraries like React Transition Group or Framer Motion.
Scroll Restoration
By default, React Router will automatically restore the scroll position when the user navigates with the browser‘s back/forward buttons. But if you want scrolling to the top on every navigation, you can use the ScrollToTop
component.
Query Parameters
You can easily parse and manipulate query parameters using the useQuery
hook from the query-string
library.
Common Use Cases and Recipes
Let‘s look at some common use cases and recipes you might encounter when building React applications with React Router.
Authentication Flows
A typical authentication flow involves redirecting a user to a login page when they try to access a private route, and redirecting them back to the private route once they‘re authenticated.
Preventing Navigation with Prompt
The Prompt
component lets you prevent a user from navigating away from a page, for example if they have unsaved changes in a form.
Custom Link Components
You can build your own custom Link
component to render something other than an <a>
tag, for example a button or an image.
Route-Based Code Splitting
With route-based code splitting, a given route‘s components are loaded only when that route is rendered. This can dramatically reduce the size of your initial bundle.
Conclusion
We‘ve covered a lot of ground in this guide to React Router. We started with the basics of installation and setup, then delved into the core concepts of routing, linking, redirecting, and using parameters and hooks to access route data.
We also touched on some more advanced topics and recipes like code splitting, scroll restoration, animated transitions, and more.
Remember, React Router is a powerful tool, but it does have a bit of a learning curve. Don‘t be afraid to refer back to this guide whenever you need to refresh your knowledge or find a quick code snippet.
Mastering React Router is an essential skill for any React web developer. With the knowledge you‘ve gained from this cheatsheet, you should now feel confident implementing client-side routing in your React applications.
So go forth and build some amazing web apps with React and React Router! Happy coding!