The future of Reach Router and React Router
Tags: react
Published: 2020-04-29 20:41:23

---
title: The future of Reach Router and React Router
published: true
date: 2020-04-03 13:00:36 UTC
tags: react
canonical_url: https://blog.logrocket.com/future-reach-router-react-router/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/chhcy1m1tg7ud011wb2j.jpeg
---
**Written by [Yusuff Faruq](https://blog.logrocket.com/author/yusufffaruq/)**✏️

In May of 2019, Ryan Florence, co-creator of React Router and Reach Router, [announced](https://reacttraining.com/blog/reach-react-router-future/) the impending release of a new version of React Router that takes advantage of React’s Hooks API. He also stated that React Router would be the surviving project, while Reach Router will continue to receive support in the form of bug fixes.

Fast-forward to September 2019, and React Router v5.1 was eventually released. This version is an introduction to the new Hooks-based API and comes with some amazing features. The new Hooks also make routing easier.

In this article, I will talk about the new features in React Router, compare Reach Router (and React Router) to the new Hooks-based API, and briefly discuss how to migrate to this API.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## The Hooks

### The `useHistory` Hook

A new addition to React Router is the `useHistory` Hook, which gives you access to the “history” instance from the history package, one of React Router’s major dependencies. The history object allows for programmatic navigation between routes in your React apps.

In React Router v4, to access the `history` object, you had to use the `history` prop.  
Let’s say we wanted to programmatically navigate to a route called `home` using a button. With React Router v4, our code would look similar to this:

```jsx
function HomeButton({history}) {
  function handleClick() {
    history.push("/home");
  }
  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}
```

However, with the introduction of the `useHistory` Hook, we can easily access the `history` object and use it like so:

```jsx
import { useHistory } from "react-router-dom";

function HomeButton() {
  const history = useHistory();
  function handleClick() {
    history.push("/home");
  }
  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}
```

If the user clicks on the button, the `home` entry will be pushed onto the `history` stack, and the home page will be rendered.

### The `useLocation` Hook

The next Hook we will discuss is `useLocation`. This Hook returns the `location` object, which represents the current URL. The `location` object can also be used to access data sent from another route using the `location` object’s state property.

In React Router v4 and Reach Router, to gain access to the `location` object, you had to access them using props or, in the case of Reach Router, a `Location` component.

This is how you would access the `location` object with React Router v4:

```jsx
function RandomRoute({ location }) {
  return <h1>Current pathname: {location.pathname}</h1>;
}
```

And this is how you would access the `location` object in Reach Router:

```jsx
function RandomRoute() {
  return (
    <Location>
      {({ location }) => <h1>Current pathname: {location.pathname}</h1>}
    </Location>
  );
}
```

Now, with the new `useLocation` Hook, you can access the `location` object more conveniently, like so:

```jsx
function RandomRoute() {
  const location = useLocation();
  return <h1>Current pathname: {location.pathname}</h1>;
}
```

### The `useParams` Hook

React Router v5.1 also gives us the new `useParams` Hook. This Hook returns an object of key-value pairs of URL parameters. URL parameters, commonly used among React Router and Reach Router users, allow us to conveniently pass information about a click through a URL.

In Reach Router and previous versions of React Router, the only way we could access URL parameters was through props and, in the case of Reach Router, the `Match` component.

So, with React Router v4, we would have to do something like this:

```jsx
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";
function App() {
  return (
    <Router>
      <header>
        <nav>
          <Link to="/">Home</Link>
          <Link to = "/page/2">Page 2</Link>
        </nav>
      </header>
      <Switch>
        <Route path = "/page/:pageNumber" component = {Page}>
        <Route path="/" render={() => <h1>Home</h1>} />
      </Switch>
    </Router>
  );
}
function Page({match}) {
  const {pageNumber} = match.params;
  return <h1>Page Number:{pageNumber}</h1>;
}
```

Or something like this, in the case of Reach Router:

```jsx
import { Router, Link } from "@reach/router";
function App() {
  return (
    <>
      <header>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/page/2">Page 2</Link>
        </nav>
      </header>
      <Router>
        <Home path="/" />
        <Page path="/page/:pageNumber" />
      </Router>
    </>
  );
}
const Home = () => <h1>Home</h1>;
function Page(props) {
  return <h1>Page Number:{props.pageNumber}</h1>;
}
```

The above methods work fine for most cases. But if you are trying to pass URL parameters down to child components, you would have to pass them them as props, which can make your code messy.

With the new Hooks API, you can easily call the `useParams` Hook in any child component to get the URL parameters. If we were to rewrite our code to use Hooks, it would look something like this:

```jsx
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useParams
} from "react-router-dom";
function App() {
  return (
    <Router>
      <header>
        <nav>
          <Link to="/">Home</Link>
          <Link to = "/page/2">Page 2</Link>
        </nav>
      </header>
      <Switch>
        <Route path = "/page/:pageNumber">
          <Page />
        </Route>
        <Route path="/" render={() => <h1>Home</h1>} />
      </Switch>
    </Router>
  );
}
function Page() {
  const {pageNumber} = useParams();
  return <h1>Page Number:{pageNumber}</h1>;
}
```

### The `useRouteMatch` Hook

The last new Hook is `useRouteMatch`. In Reach Router, if you wanted to access the `match` object of a Route, you would have to use the `Match` component. And if you were using a previous version of React Router, you would have to use the route’s props or render props. With this new Hook, it’s easier and more convenient to access `match` object!

The Hook takes in a path as an argument and returns a corresponding `match` object. When no argument is passed, the Hook returns a `match` object based on the closest matching `<Route>` in the tree.

Former way of accessing a match object in React Router:

```jsx
//option 1
function ARoute() {
  return (
    <Route
      path="/randomroute/:randomrouteid"
      render={({ match }) => {
        return (
          ...
        );
      }}
    />
  );
}

//option 2
function ARoute(props){
  const match = props.match;
  return (
    ...
  );
}
```

To get the `match` object in Reach Router, we would have to use the provided `Match` component:

```jsx
function AnotherRandomRoute(){
    return(
        <Match path = "/randomroute/:randomrouteid">
            {
                ({match}) => ...
            }
        </Match>
    );
}
```

The above code blocks work fine, but we can make our code shorter and cleaner with the `useRouteMatch` Hook, like so:

```jsx
function AnotherRandomRoute(){
    const match = useRouteMatch("/randomroute/:randomrouteid");
    return(
        ...
    );
}
```

With `useRouteMatch`, you can also implement nested routing using the `url` and `path` properties of the `match` object. Here’s an example of how you might handle nested routing in React Router with this Hook:

```jsx
function Topics() {
  const { path, url } = useRouteMatch();
  return (
    <div>
      <div>
        <Link to={`${url}/1`}>Topic 1</Link>
        <Link to={`${url}/2`}>Topic 2</Link>
        <Switch>
          <Route exact path={path} render={() => <h1>Select a topic</h1>} />
          <Route path={`${path}/:topic`}>
            <Topic />
          </Route>
        </Switch>
      </div>
    </div>
  );
}
function Topic() {
  const { topic } = useParams();
  return (
    <div>
      <h1>Topic: {topic}</h1>
    </div>
  );
}
```

`useRouteMatch` is also useful any time you would use a `Route` component outside a `Switch` component.

## Updates to the `Link` and `NavLink` components

React Router v5.1 also added some updates to the `Link` and `NavLink` components, one of which is the ability to pass in functions to these components’ `to` props. The current location is passed as an argument to the function, and this function must return a location representation in the form of an object or a string.

## React Router v6

Currently, a major version of React Router is [in the works](https://github.com/ReactTraining/react-router/releases/tag/v6.0.0-alpha.2). React Router v6, which is currently in the alpha stage, will have the following features:

- A smaller bundle size. The current size of the new version in a fully migrated app is around 3kB. According to [a tweet](https://twitter.com/mjackson/status/1229156979714605056?s=20) by Michael Jackson, co-creator of React Router, they were able to achieve this by dropping support for anything older than IE11, dropping support for React <16.8, using Google Closure Compiler, and writing better code
- Automatic `<Route>` ranking with a new `<Routes>` API. `<Routes>` will replace `<Switch>`
- Nested route configs (much like React Router v3 and Reach Router)
- New Suspense-ready `navigate` API
- `useRoutes` and `matchRoutes` for using object-based routing API
- A new Hook called `useNavigate`, which returns a function for programmatic routing/navigation.

## Migrating from Reach Router to the new Hooks-based API

If you are planning to migrate from Reach Router, it’s easier to migrate to React Router v6 because they look similar at surface level. You can easily migrate by following these steps:

- Install React Router v6
- Replace `<Location>` and `<Match>` with the `useLocation` and `useRouteMatch` Hooks
- Use `useParams` to access URL parameters
- Put a `<BrowserRouter>` on top:

```jsx
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);
```

- Replace `<Router>` with `<Routes>` and define your routes using `<Route>`

## Conclusion

So far, React Router v6 is looking very promising. The new features and Hooks will definitely encourage cleaner code, and I think it was a great decision on the part of the React Router team to move towards building a Hooks-based API.

* * * 
## Full visibility into production React apps 

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket.](https://www2.logrocket.com/react-performance-monitoring)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eq752g8qhbffxt3hp9t4.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free.](https://www2.logrocket.com/react-performance-monitoring)
* * *

The post [The future of Reach Router and React Router](https://blog.logrocket.com/future-reach-router-react-router/) appeared first on [LogRocket Blog](https://blog.logrocket.com).