React Router Hooks - How To Use Them
Tags: react, todayisearched, javascript
Published: 2020-02-11 22:15:11

I know I'm a little behind the ball, but a few months ago React-Router released a new update that introduced [hooks](https://reacttraining.com/react-router/web/api/Hooks) to their API. 

 
This update now allows users access to the state of the router and the ability to perform navigation from inside components by using the `useHistory`, `useParams`, `useLocation`, and `useRouteMatch` hooks. 

Today, I'll be giving you a brief overview of each of the hooks and how they've changed the way we write routes. 

# `useHistory` 

The `useHistory` hook gives you access to the `history` object that you can use to navigate routes. 

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

const Homepage = () => {
  let history = useHistory()
  
  function goBack(){
    history.goBack()
  }

  function goHome(){
    history.push('/')
  } 

  return(
    <div>
      <button onClick={goBack}>Previous</button>
      <button onClick={goHome}>Home</button>
    </div>
 )
}

export default Homepage
```

The `history` object will give us access to the following properties and methods: 

* length - (number) The number of entries in the history stack
* action - (string) The current action (PUSH, REPLACE, or POP)
* location - (object) The current location. May have the following properties:
      * pathname - (string) The path of the URL
      * search - (string) The URL query string
      * hash - (string) The URL hash fragment
      * state - (object) location-specific state that was provided to e.g. push(path, state) when this location was pushed onto the stack. Only available in browser and memory history.
* push(path, [state]) - (function) Pushes a new entry onto the history stack
* replace(path, [state]) - (function) Replaces the current entry on the history stack
* go(n) - (function) Moves the pointer in the history stack by n entries
* goBack() - (function) Equivalent to go(-1)
* goForward() - (function) Equivalent to go(1)
* block(prompt) - (function) Prevents navigation

# `useParams`

The `useParams` hook gives you access to the params of the given route. Params are just parameters on a given URL that is dynamically set.

Before the `useParams` hook was introduced by React-Router you had to access the params through props that were passed down to the component like so

```jsx
import React from "react"
import ReactDOM from "react-dom"
import {
  BrowserRouter as Router,
  Switch,
  Route
} from "react-router-dom"

function Post(props) {
  let { id } = props.match.params
  return <div>Now showing post {id}</div>
}

function App(){
  return(
   <div className='app'>
    <Router>
      <Switch>
        <Route exact path="/" component={Homepage} />
        <Route 
          path="/blog/:id"
          render={routerProps => (
           <Post {...routerProps}/>
          )}
          />
      </Switch>
    </Router>
   </div>
 )
}
```

Now all you need to do is call the `useParams` hook to have access to the params.

```jsx
import React from "react"
import ReactDOM from "react-dom"
import {
  BrowserRouter as Router,
  Switch,
  Route,
  useParams
} from "react-router-dom"

function Post(props) {
  let { id } = useParams()
  return <div>Now showing post {id}</div>
}

function App(){
  return(
   <div className='app'>
    <Router>
      <Switch>
        <Route exact path="/" />
          <Homepage />
        </Route>
        <Route path="/blog/:id">
          <Post />
        </Route>
      </Switch>
    </Router>
   </div>
 );
}
```

# `useLocation`

Another hook that now ships with the React-Router update is the `useLocation` hook. 

This hook will give you access to the `location` object that represents the current URL. The official documentation said that you can view the `useLocation` hook as `useState` that returns a new `location` every time the URL is updated.

```jsx
import React from "react"
import ReactDOM from "react-dom"
import {
  BrowserRouter as Router,
  Switch,
  useLocation
} from "react-router-dom"

const LearnMore = () => {
  let location = useLocation()
  return(
    <div>
      You are currently at the following path {location.pathname}
    </div>
  )
 }

function App(){
 return(
  <div className='app'>
    <Router>
     <ul>
        <li>
            <Link to='/'>Home</Link>
        </li>
        <li>
            <Link to='/learn-more'>Learn More</Link>
        </li>
     </ul>
     <Switch>
       <Route exact path='/'>
          <HomePage />
       </Route>
       <Route path='/learn-more'>
          <LearnMore />
       </Route>
     </Switch>
    </Router>
  </div>
 )
}
```


# `useRouteMatch`

Finally, the `useRouteMatch` hook will give you access to the `match` property without actually rendering a `<Route>` component. 

Previously you had to use the `render` prop function to handle this like so

```jsx
import { Route } from "react-router-dom"

function AnimalCard() {
  return (
    <Route
      path="/animal/:id"
      render={({ match }) => {
        // Do some stuff with your match...
        return <div />
      }}
    />
  );
}
```

Now you can just import the hook and render elements once the route matches

```jsx
import { useRouteMatch } from "react-router-dom"

function AnimalCard() {
  let match = useRouteMatch("/animal/:id")

  // Do some stuff with your match...
  return <div />;
}
```

One thing that is extremely helpful about the `useRouteMatch` hook is that it accepts `strict`, `exact`, `path`, and `sensitive` options as well. 


# Conclusion

Well, there you have it! A quick look at the React-Router hooks. Try these out with your next project and check out the full documentation [here](https://reacttraining.com/react-router/web/guides/quick-start)