React Router hooks will make your component cleaner
Tags: react, javascript, webdev
Published: 2020-02-26 15:24:12

---
title: React Router hooks will make your component cleaner
published: true
date: 2020-02-24 14:15:56 UTC
tags: react, javascript, webdev
canonical_url: https://blog.logrocket.com/react-router-hooks-will-make-your-component-cleaner/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/rlfz9mo4oazf699pmgjp.png
---
**Written by [Nathan Sebhastian](https://blog.logrocket.com/author/nathansebhastian/)**✏️

React Router is a lightweight library that allows you to manage and handle routing for your React application.

Among the most prominent features of React Router are [route render methods](https://reacttraining.com/react-router/web/api/Route/route-render-methods), which enable your component to access `match`, `location`, and `history` props. Together, these props are used to pass data from URL to component and navigate your React application programmatically.

For example, if you’d like to create a back button, you can use the `goBack()` function from `history` props. This abstracts away the differences in various environments or web browsers so you can go back to the previous webpage in a simple function.

```jsx
// a Route with component props
<Route path="/post/:number" component={Post} />

// The component itself
function Post(props) {
  return (
    <div>
      In React Router v4, you get the history object from props. <br />
      <button type="button" onClick={() => props.history.goBack()}>
        Go back
      </button>
    </div>
  );
}
```

Although this works fine, the route render method is widely considered hard to read and just plain weird. That’s why, starting with [version 5.1](https://reacttraining.com/blog/react-router-v5-1/), React Router will include four useful hooks you can use to write clean, neatly stacked navigation components that please the eye. I’ll show you how these new hooks work by comparing them to the old patterns in version 4.

We’ll start with the `useParams` hook.

[![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/)

## `UseParams`

The `useParams` hook will return an object of key/value pairs from your application URL that is set to be dynamic. In a complex application, it’s common to have many navigation links that are dynamic.

For example, you may have a `/post/:id` URL that also initiates a fetch process to your application’s backend. In this case, the most common React Router pattern would be to use a component prop.

```jsx
export default function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/post/hello-world">First Post</Link>
            </li>
          </ul>
        </nav>
        <Switch>
          <Route path="/post/:slug" component={Post} />
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}
```

By passing the `Post` component into the `/post/:number` `Route` component, you can extract the `params` object from the `match` prop that is passed by React Router into the `Post` component.

```jsx
// Old way to fetch parameters
function Post({ match }) {
  let params = match.params;
  return (
    <div>
      In React Router v4, you get parameters from the props. Current parameter
      is <strong>{params.slug}</strong>
    </div>
  );
}
```

This method works just fine, but it’s quite cumbersome if you have a big application with lots of dynamic routes. You have to keep track of which `Route` components need component props and which do not. Also, since the `match` object is passed from `Route` into the rendered component, you will need to pass them along to components further down the DOM tree.

This is where the `useParams` hook really shines. It’s a neat helper function that gives you the parameters of the current route so you don’t have to use the component props pattern.

```jsx
<Switch>
  <Route path="/post/:slug" component={Post} />
  <Route path="/users/:id/:hash">
    <Users />
  </Route>
  <Route path="/">
    <Home />
  </Route>
</Switch>

function Users() {
  let params = useParams();
  return (
    <div>
      In React Router v5, You can use hooks to get parameters.
      <br />
      Current id parameter is <strong>{params.id}</strong>
      <br />
      Current hash parameter is <strong>{params.hash}</strong>
    </div>
  );
}
```

If a child component of `Users` need access to the parameters, you can simply call `useParams()` there as well.

Here’s an [example](https://codesandbox.io/s/react-router-useparams-hooks-qo2rd) if you’d like to see it in action.

## `UseLocation`

In React Router version 4, just like fetching parameters, you had to use the component props pattern to gain access to a `location` object.

```jsx
<Route path="/post/:number" component={Post} />

function Post(props) {
  return (
    <div>
      In React Router v4, you get the location object from props. <br />
      Current pathname: <strong>{props.location.pathname}</strong>
    </div>
  );
}
```

With version 5.1, you can call the `useLocation` hook to get the `location` object from React Router.

```jsx
<Route path="/users/:id/:password">
  <Users />
</Route>

// new way to fetch location with hooks
function Users() {
  let location = useLocation();
  return (
    <div>
      In React Router v5, You can use hooks to get location object.
      <br />
      Current pathname: <strong>{location.pathname}</strong>
    </div>
  );
}
```

Again, you can see the sample code on [CodeSandbox](https://codesandbox.io/s/react-router-uselocation-hooks-0cuvn).

## `UseHistory`

That gives us one less reason to use component props. But don’t you still need to use the component or render pattern to get the `history` object?

The `history` object is the last reason why you need to use component or render props pattern.

```jsx
<Route path="/post/:slug" component={Post} />

// Old way to fetch history
function Post(props) {
  return (
    <div>
      In React Router v4, you get the history object from props. <br />
      <button type="button" onClick={() => props.history.goBack()}>
        Go back
      </button>
    </div>
  );
}
```

By using the `useHistory` hook, you can get the same history object without needing the `Route` component to pass it down.

```jsx
<Route path="/users/:id/:hash">
  <Users />
</Route>

// new way to fetch history with hooks
function Users() {
  let history = useHistory();
  return (
    <div>
      In React Router v5, You can use hooks to get history object.
      <br />
      <button type="button" onClick={() => history.goBack()}>
        Go back
      </button>
    </div>
  );
}
```

See this [sample code](https://codesandbox.io/s/react-router-usehistory-hooks-0cqd0) for a comparison between `useHistory` and regular `history` props.

Now you can have a clean routing component without any weird component compositions that use `component` or `render` props. You can simply put a `<Route>` component with `path` props and place the rendered `children` component inside it.

## `useRouteMatch`

Sometimes, you need to use the `<Route>` component just to get access to a `match` object.

```jsx
<Route path="/post">
  <Post />
</Route>

function Post() {
  return (
    <Route
      path="/post/:slug"
      render={({ match }) => {
        return (
          <div>
            Your current path: <strong>{match.path}</strong>
          </div>
        );
      }}
    />
  );
}
```

The example above shows one way to access a `match` object without using the `component` or `render` props. With the latest version of React Router, you can also use the `useRouteMatch` hook, which enables you to grab the `match` object and use it inside your component without using `<Route>`.

```jsx
<Route path="/users">
  <Users />
</Route>

// useRouteMatch to make your route above cleaner
function Users() {
  let match = useRouteMatch("/users/:id/:hash");
  return (
    <div>
      In React Router v5, You can use useRouteMatch to get match object. <br /> Current match path: <strong>{match.path}</strong> </div> ); }
```

Now you won’t need to create a `<Route>` component just to grab a `match` object. Here’s another [example](https://codesandbox.io/s/react-router-useroutematch-hooks-w2p5g) for you to mess around with.

## Conclusion

The React Router team harnessed the power of hooks and implemented it to share logic across components without the need to pass it down from from the top of the tree.

If you’d like to refactor your component with these new hooks, you can start by updating components that use `match`, `location`, or `history` objects.

```jsx
// before
function userComponent({ match, location, history }) {
  let { slug } = match.params
  // ...
}

// after
function userComponent() {
  let { slug } = useParams()
  let location = useLocation()
  let history = useHistory()
  // ...
}
```

After that, you can update the weird-looking `<Route>` components you might have in your navigation component.

```jsx
// before
<Switch>
  <Route path="/user/:id" component={userComponent} />
</Switch>

// after
<Switch>
  <Route path="/user/:id">
    <userComponent />
  </Route>
</Switch>
```

What do you think about React Router hooks? Share your comments below.

* * * 
## 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 [React Router hooks will make your component cleaner](https://blog.logrocket.com/react-router-hooks-will-make-your-component-cleaner/) appeared first on [LogRocket Blog](https://blog.logrocket.com).