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 Routes 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!

Similar Posts