- Published on
How to Programmatically Navigate Using React Router
- Authors
- Name
- Ripal & Zalak
Introduction
In React Router, navigation is commonly handled using the <Link>
component. However, there are situations where programmatic navigation is required, such as navigating based on a user action like a button click or a dropdown selection. This blog explores the modern and legacy approaches to programmatically navigate using React Router.
useNavigate
React Router v6: Using React Router v6 introduced the useNavigate
hook, which replaces the deprecated useHistory
hook. This hook provides a simple way to programmatically navigate within your application.
Example
import { useNavigate } from 'react-router-dom'
function HomeButton() {
const navigate = useNavigate()
function handleClick() {
navigate('/home')
}
return (
<button type="button" onClick={handleClick}>
Go Home
</button>
)
}
useNavigate
:
Key Features of - Accepts a path to navigate to.
- Allows options like
replace: true
to replace the current history entry instead of adding a new one.
Advanced Example with State
You can pass state along with navigation:
navigate('/profile', { state: { userId: 123 } })
To access this state in the target component:
import { useLocation } from 'react-router-dom'
function ProfilePage() {
const location = useLocation()
console.log(location.state.userId)
}
useHistory
React Router v5: Using For applications using React Router v5, the useHistory
hook is used for programmatic navigation.
Example
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>
)
}
useNavigate
and useHistory
Differences Between While useHistory
works similarly to useNavigate
, it is now deprecated in favor of the cleaner and more feature-rich useNavigate
.
Legacy Approaches in React Router v4
withRouter
1. Using The withRouter
higher-order component provides access to the history
object as a prop.
import { withRouter } from 'react-router-dom'
const Button = withRouter(({ history }) => (
<button type="button" onClick={() => history.push('/new-location')}>
Click Me
</button>
))
<Route>
Component
2. Using You can render a pathless <Route>
to always match the current location and use the history
prop it provides.
import { Route } from 'react-router-dom'
const Button = () => (
<Route
render={({ history }) => (
<button type="button" onClick={() => history.push('/new-location')}>
Click Me
</button>
)}
/>
)
Legacy Context API (Not Recommended)
In earlier versions of React Router, the context
API could be used to access the history
object. However, this approach is not recommended as it tightly couples components to React Router’s implementation.
Example
class Button extends React.Component {
static contextTypes = {
history: PropTypes.shape({
push: PropTypes.func.isRequired,
}),
}
render() {
return (
<button type="button" onClick={() => this.context.history.push('/new-location')}>
Click Me
</button>
)
}
}
Best Practices for Programmatic Navigation
- Use Hooks for Modern React Projects: Prefer
useNavigate
for React Router v6 oruseHistory
for v5. - Avoid Legacy Approaches: Context-based navigation and mixins are outdated and should be avoided.
- Centralize Navigation Logic: For complex apps, consider creating a reusable navigation utility or service.
- Ensure Accessibility: Always ensure navigation methods maintain accessibility standards, such as using buttons for click actions.
Conclusion
Programmatic navigation in React Router has evolved significantly over time. With the modern useNavigate
hook, navigating programmatically has become cleaner and more intuitive. By understanding these approaches and best practices, you can effectively handle navigation in any React Router version.