DEV Community

Sarah Katz
Sarah Katz

Posted on

React-Router Hooks: A Brief Introduction

React-Router, a popular declarative routing library for React, recently released hooks as part of their API. I came across one of these hooks as part of my work, and I thought it would be interesting to dig into them a little bit more.

This article provides a very basic overview of the four hooks that were included with React Router v5.1. This is by no means a comprehensive article, but my goal is to provide information to help you decide whether it would be worth trying to implement these hooks in your app.

Four hooks were introduced with this release - useParams, useHistory, useLocation, and useRouteMatch.

useParams

This hook is intended for use in any situation where you would have used match.params. For example, if you're looking to get the id in the url www.mysite.com/page/:id, here's how your code could change:

Old Code:

const { id } = props.match.params;

New Code:

const { id } = useParams();

While the cleaner-looking code would be enough of a reason for me to use it, useParams actually has one even bigger advantage - it allows you to access params anywhere in the component tree without explicitly passing them down. For example, if you have ComponentA which calls ComponentB, here's how your code might change:

Old Code:

// Component A:
const ComponentA = (props) => {
  const { id } = props.match.params;
  return <ComponentB id={id} />;
}
export const RoutedComponentA = withRouter(ComponentA);

// Component B:
const ComponentB = (props) => (<div>My ID is: {props.id}</div>);

New Code:

const ComponentA = () => {
  return <ComponentB />;
}

// Component B:
const ComponentB = () => {
  const { id } = useParams();
  return (<div>My ID is: {id}</div>);
}

I'm always appreciative of an opportunity to not pass down props, so I anticipate using useParams quite a bit in the future.

useHistory

This hook provides access to the history object. useHistory is not intended as a long term solution - it will eventually be replaced by another hook called useNavigation - but it was included in this release to make it easier for teams to move away from withRouter.

This would be used in the same way as you would use props.history. For example, if you want to make a button that redirects the user to the home page any time they click it:

const BackButton = () => {
  const history = useHistory();
  return (<button onClick={() => history.push('/home')}>Paradise City</button>);
}

Any action that can be performed with the history API can also be performed with the history object returned from useHistory().

useLocation

This hook provides access to the location object, which is useful for any component that needs to know the current URL.
For example, if your app has several "FAQ" pages and you want to navigate to the FAQ page for your current location, here's how your code might change:

Old Code:

const LinkToFaqComponent = (props) => {
  return (
    <Link to=`${props.location.pathname}/faq`>
      Read Our FAQ Here!
    </Link>
  )
}

export const LinkToFaq = withRouter(LinkToFaqComponent)

New Code:

export const LinkToFaq = () => {
  const location = useLocation();
  return (
    <Link to=`${location.pathname}/faq`>
      Read Our FAQ Here!
    </Link>
  )
}

The difference in this example isn't that large, but the more complex your location-related logic is, the more you will see a difference with the use of the useLocation hook.

useRouteMatch

This hook is used when you just want route match data without actually having to render the route. I haven't seen this hook used in action, so I'll direct you to the official documentation for an example of its use for this purpose.

Takeaways

Seeing React-Router introduce hooks is a great thing, but it doesn't mean that everyone should rush to put these hooks in all of your apps right now. withRouter is still supported and will continue to be supported in React Router v6 (whenever that comes). If your app isn't designed in a way that you can easily convert to using hooks, that may be a good use case for continuing to use withRouter.

That said ... if you're creating a new functional component (or you're refactoring a class component that can easily be converted into a functional component) and you need access to route props, this would be a great opportunity to start using these new hooks. Hooks are the future of React and several other libraries that are popular in React applications (including react-redux and react-router), so the more you make hooks part of your regular development, the easier it will be to adapt to future changes.

Top comments (0)