How to programmatically navigate using React Router?
Building a React application that relies heavily on user interactions and dynamic routing often requires programmatic navigation—redirecting users after form submissions, API responses, or other conditional logic. While the <Link> and <NavLink> components handle most navigation scenarios, there are times you’ll want finer control. Below, we’ll explore how to navigate programmatically with both React Router v5 and v6, highlight common mistakes, and offer best practices.
Understanding React Router’s Evolution
React Router has undergone several changes over time. Before version 6, developers commonly used the useHistory hook or the withRouter Higher-Order Component (HOC). In React Router v6, the recommended approach is the useNavigate hook. Let’s break these down.
Programmatic Navigation in React Router v5
1. The useHistory Hook
In React Router v5, useHistory() is your gateway to the history instance for pushing or replacing routes.
import React from 'react';
import { useHistory } from 'react-router-dom';
function Login() {
const history = useHistory();
const handleLogin = () => {
// Perform login logic
history.push('/dashboard'); // Navigate to dashboard
};
return (
<button onClick={handleLogin}>Log In</button>
);
}
export default Login;
2. The withRouter HOC
If you’re working with class components or prefer not to use hooks, you can wrap components with withRouter. It injects history, location, and match props into your component.
import React from 'react';
import { withRouter } from 'react-router-dom';
class Dashboard extends React.Component {
handleProfileRedirect = () => {
this.props.history.push('/profile');
};
render() {
return (
<button onClick={this.handleProfileRedirect}>
Go to Profile
</button>
);
}
}
export default withRouter(Dashboard);
Programmatic Navigation in React Router v6
React Router v6 replaces useHistory with useNavigate. The useNavigate hook returns a function you can call to navigate programmatically.
import React from 'react';
import { useNavigate } from 'react-router-dom';
function Home() {
const navigate = useNavigate();
const goToAbout = () => {
navigate('/about');
};
return (
<button onClick={goToAbout}>Go to About</button>
);
}
export default Home;
1. navigate('/route') vs. navigate(-1)
navigate('/route'): Jumps directly to a specified route.navigate(-1): Equivalent to the browser’s back button, moving one step backward in history.
Recommended Courses
2. Replace vs. Push
By default, navigate('/route') pushes a new entry into the history stack. Use { replace: true } if you don’t want the user to go back to the previous page:
navigate('/dashboard', { replace: true });
Handling Conditional Routing
Sometimes, you only want to navigate if certain conditions are met (e.g., successful server response or valid user authentication). Simply wrap your navigation call in conditional checks:
if (response.status === 200) {
navigate('/dashboard');
} else {
alert('Something went wrong!');
}
Common Pitfalls and Best Practices
Incorrect Hook Usage
- Avoid mixing up versions.
useHistorywon’t work in React Router v6, anduseNavigateisn’t recognized by older versions.
- Avoid mixing up versions.
Excessive Navigations
- Calling
navigate()too often can disrupt the user experience. Keep your logic streamlined.
- Calling
Authentication & Protected Routes
- Use
navigate()within higher-order authentication logic or context-based components to redirect users who aren’t authorized.
- Use
Maintainable Navigation Logic
- Centralize your routing in one area to avoid scattered navigation logic, making it easier to update as your app evolves.
Leveling Up Your React & JavaScript Skills
Knowing how to implement programmatic navigation is just a start. If you’re aiming to become a more complete engineer—whether that’s solidifying JavaScript fundamentals or conquering complex interview questions—consider the following resources from DesignGurus.io:
Grokking JavaScript Fundamentals
Strengthen your JavaScript foundation, which in turn makes you a more confident and effective React developer.Grokking the Coding Interview: Patterns for Coding Questions
If you’re preparing for coding interviews and want to master the most popular patterns, this course offers structured guidance with real-world examples.System Design Primer The Ultimate Guide
Ideal for developers looking to expand beyond front-end into designing scalable, high-performance back-end architectures.
For live, personalized practice, consider DesignGurus.io’s Coding Mock Interview sessions with ex-FAANG engineers. You’ll receive detailed feedback, pinpoint areas of improvement, and build confidence for real interview scenarios.
Conclusion
Programmatic navigation is essential for building dynamic, user-friendly React applications. With React Router v5, you’ll use useHistory() or withRouter. In v6, useNavigate is the go-to solution, offering clean, maintainable code for complex routing scenarios. Remember to be mindful of user experience—navigate intentionally, handle edge cases, and keep your code organized.
Once you’re comfortable with routing, keep expanding your skill set. Whether diving into advanced JavaScript or preparing for system design interviews, the offerings at DesignGurus.io can guide you along the way. Armed with the right knowledge and practice, you’ll create seamless, robust React applications that stand out in today’s competitive tech landscape. Happy coding!