Programmatic Navigation in React Router: A Complete Guide from v4 to v6.6.1
Navigating programmatically is a core aspect of building single-page applications (SPAs) with React Router. Over the years, React Router has evolved, and each version has introduced new methods to simplify the process. This guide will cover how to perform programmatic navigation from React Router v4 to v6.6.1, highlighting the best practices for each version.
Table of Contents
- React Router v6.6.1+:
useNavigate
Hook - React Router v5.1.0:
useHistory
Hook - React Router v4:
withRouter
HOC and Other Techniques
React Router v6.6.1+: useNavigate
Hook
With React Router v6, the useHistory()
hook was replaced by useNavigate()
. This hook provides a more streamlined approach to programmatic navigation, making it easy to redirect users with functional components.
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>
);
}
Here, useNavigate
replaces useHistory
. By calling navigate("/home")
, the user is redirected to the specified path.
React Router v5.1.0: useHistory
Hook
In React Router v5.1.0, useHistory()
was introduced for functional components, simplifying the process of programmatic navigation in apps using React >=16.8.0.
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>
);
}
Here, history.push("/home")
adds a new location to the browser history stack, allowing users to navigate backward.
React Router v4: withRouter
HOC and Other Techniques
With React Router v4, there were multiple ways to achieve programmatic navigation. Let’s go over the three main options:
- Using the
withRouter
Higher-Order Component (HOC) ThewithRouter
HOC injects thehistory
object as a prop, enabling access to navigation methods.
import { withRouter } from "react-router-dom";
const Button = withRouter(({ history }) => (
<button
type="button"
onClick={() => history.push("/new-location")}
>
Click Me!
</button>
));
- Rendering a
<Route>
By rendering a pathless<Route>
, you can access thehistory
prop directly within the component.
import { Route } from "react-router-dom";
const Button = () => (
<Route render={({ history }) => (
<button
type="button"
onClick={() => history.push("/new-location")}
>
Click Me!
</button>
)} />
);
- Using Context (Not Recommended) Directly accessing
history
from context is an option but should generally be avoided.
const Button = (props, context) => (
<button
type="button"
onClick={() => {
context.history.push("/new-location");
}}
>
Click Me!
</button>
);
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired,
}),
};
Using withRouter
or <Route>
is often the preferred approach due to better compatibility with React’s evolving API.
Conclusion
React Router’s navigation methods have evolved, providing cleaner and simpler hooks over time. Starting with withRouter
in v4 and progressing to useNavigate
in v6, the library continues to adapt to modern React practices. When building new projects, it’s best to rely on useNavigate
for the latest features and better performance.
Let us know your favorite approach to programmatic navigation in the comments below!
This layout keeps information concise, with clear versioning and examples for readers to follow along with each version’s method of programmatic navigation.