I know I'm a little behind the ball, but a few months ago React-Router released a new update that introduced 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.
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
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.
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.
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
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
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
Top comments (0)