Programmatic Navigation
In this page:
Navigating After an Action, Not a Click
Sometimes navigation needs to happen as a result of code running, like redirecting after a successful form submission, rather than the user clicking a Link directly. The useNavigate() hook returns a function you can call from inside any event handler or effect to trigger that navigation.
Note: Call navigate() right after your async submit logic succeeds, so the redirect only happens if the action actually worked.
Warning: useNavigate() must be called inside a component rendered within a BrowserRouter — calling it outside that context throws an error.
Example: Navigating After an Action, Not a Click
// Run in your local React project (npm install required)
import { useNavigate } from 'react-router-dom';
function LoginForm() {
const navigate = useNavigate();
const handleSubmit = e => {
e.preventDefault();
navigate('/dashboard');
};
return <form onSubmit={handleSubmit}><button type="submit">Log In</button></form>;
}
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
Going Back with navigate(-1)
Passing a negative number to navigate acts like the browser's back button, moving that many steps backward through history. navigate(-1) goes back one page, mimicking a Cancel or Back button's natural behavior.
Note: This is a nice way to implement a generic Back button that works no matter where the user came from.
Warning: If there's no previous entry in history (e.g. the user landed directly on this page), navigate(-1) can navigate away from your app entirely.
Example: Going Back with navigate(-1)
// Run in your local React project (npm install required)
import { useNavigate } from 'react-router-dom';
function BackButton() {
const navigate = useNavigate();
return <button onClick={() => navigate(-1)}>Go Back</button>;
}
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
Replacing History Instead of Pushing
By default, navigate('/path') adds a new entry to browser history, so the back button returns to the previous page. Passing { replace: true } as a second argument instead swaps out the current entry, which is useful after a login redirect so the back button doesn't return to the login form.
Note: Use replace:true for redirects the user shouldn't be able to undo with the back button, like post-login or post-logout redirects.
Warning: Overusing replace:true elsewhere can confuse users by breaking their expected back-button behavior.
Example: Replacing History Instead of Pushing
// Run in your local React project (npm install required)
import { useNavigate } from 'react-router-dom';
function LoginForm() {
const navigate = useNavigate();
const handleSubmit = e => {
e.preventDefault();
navigate('/dashboard', { replace: true });
};
return <form onSubmit={handleSubmit}><button type="submit">Log In</button></form>;
}
⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.
- Trying to use the old useHistory hook, which was removed in React Router v6 in favor of useNavigate.
- Calling useNavigate() outside of a component that's rendered inside a BrowserRouter.
- Forgetting that navigate('/path') by default adds to browser history — use { replace: true } if you want to replace instead.
- useNavigate() returns a function you call to change routes from inside event handlers or effects.
- navigate('/path') pushes a new entry onto browser history, same as clicking a Link.
- navigate(-1) goes back one step in history, like the browser's back button.
- { replace: true } as a second argument replaces the current history entry instead of adding a new one.
Requires npm install react-router-dom (v6 useNavigate) — not available via CDN in this sandbox; v5 used useHistory instead.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: