Programmatic Navigation with useHistory in React
Go beyond simple links and learn to control your application's flow based on user actions and application logic.
Login
/* How do we redirect after this form is submitted? */
The useHistory Hook: Your App's Remote Control
The `useHistory` hook gives your component access to the browser's history stack. You can think of it as a remote control for the browser's navigation. By calling this hook, you get a `history` object with methods to change routes from anywhere in your component's logic.
history.push(): Adding to the Timeline
The `history.push('/path')` method is the most common way to navigate. It adds a new entry to the history stack, so the user can click the browser's back button to return to the previous page. It's ideal for navigating after a user clicks an item or completes a step in a process.
history.replace(): Rewriting History
The `history.replace('/path')` method is similar to `push`, but it *replaces* the current entry in the history stack. This means the user cannot go back to the page they were just on. This is useful for authentication flows; after a user logs in, you don't want them to be able to click 'back' to the login screen.
history.goBack(): Traveling Back in Time
The `history.goBack()` method programmatically simulates a user clicking the browser's back button, taking them to the previous entry in the history stack. Other related methods include `goForward()` and `go(n)`, where `n` can be a positive or negative number to jump multiple steps in history.
Important Note:
The `useHistory` hook is part of React Router v5. In React Router v6 and later, it has been replaced by the more streamlined `useNavigate` hook. While the concept is the same, the syntax is different: `const navigate = useNavigate(); navigate('/path');`
Practice Zone
Interactive Test 1: Match the Method
Match the `useHistory` method to its correct description.
Arrastra en el orden correspondiente.
Arrastra las opciones:
Completa el código:
Interactive Test 2: Complete the Login
Rellena los huecos en cada casilla.
import { useHistory } from 'react-router-dom'; function LoginForm() { const history = (); const handleLogin = () => { // a login API call would go here history.('/Dashboard'); }; return <button onClick={handleLogin}>Log In</button>; }
Practice Example: Handle an Error
Imagine a user has submitted a form incorrectly. Redirect them back to the previous page so they can fix it. Use the correct `history` method.
Programmatic Navigation in Practice
Programmatic navigation is the key to creating seamless user experiences. It allows your application to react to logic and events, not just user clicks on links. Here are some common scenarios where it's indispensable.
1. Handling Form Submissions
After a user successfully submits a form (like a login, registration, or contact form), you almost always want to redirect them to another page, such as a Dashboard or a "Thank You" screen. `history.push()` or `history.replace()` inside the form's `onSubmit` handler is the perfect tool for this.
const handleSubmit = async (event) => {
event.preventDefault();
const response = await api.submitForm(data);
if (response.ok) {
history.push('/success'); // Navigate on success
}
};
2. Protecting Routes
You can protect certain parts of your application so that only authenticated users can access them. In a protected component, you can use a `useEffect` hook to check for a user session. If no session exists, you can use `history.replace('/login')` to redirect them to the login page, preventing them from using the 'back' button to re-access the protected content.
useEffect(() => {
if (!isAuthenticated) {
history.replace('/login'); // Redirect unauthenticated users
}
}, [isAuthenticated, history]);
3. Responding to API Errors
Sometimes an API call might return a specific status, like 404 (Not Found) or 401 (Unauthorized). You can inspect the response and programmatically navigate the user to a dedicated error page (`/not-found`) or force them to log in again (`/login`), providing a much better user experience than a broken page.
if (error.response.status === 404) {
history.push('/not-found');
}
Practical Takeaway: Think of programmatic navigation as the "if this, then that" for your application's routes. It's the essential tool for building dynamic, multi-step workflows that guide users through your app.
Navigation Glossary
- Programmatic Navigation
- The act of changing routes or URLs using JavaScript code in response to an event or condition, rather than a user clicking on a hyperlink.
- `useHistory` Hook
- A hook from React Router v5 that provides access to the `history` instance, which you can use to navigate programmatically.
- History Stack
- An array-like structure managed by the browser that keeps track of the pages a user has visited in a given tab. The `push`, `replace`, and `goBack` methods directly manipulate this stack.
- `push(path)`
- A method on the `history` object that navigates to a new URL and adds a new entry to the top of the history stack.
- `replace(path)`
- A method that navigates to a new URL but replaces the current entry in the history stack, making the previous page inaccessible via the browser's back button.
- `useNavigate` Hook
- The modern replacement for the `useHistory` hook in React Router v6. It offers a simpler API (`Maps('/path')`) for the same functionality.