Question
I am using React Router and understand that the Link component creates navigation links handled by the router.
I noticed that internally it appears to call something like this.context.transitionTo(...).
I want to navigate programmatically rather than from a link element—for example, after a user chooses an option from a dropdown. How can I trigger navigation in code?
Also, what exactly is this.context in this case?
I have seen the Navigation mixin mentioned in older examples, but is there a way to do this without mixins?
Short Answer
By the end of this page, you will understand how programmatic navigation works in React Router, why router state is exposed through history or router context, and how to redirect users from event handlers such as dropdown changes, form submissions, and login flows. You will also see how older approaches like this.context and mixins compare with modern React Router patterns.
Concept
Programmatic navigation means changing the current route from JavaScript code instead of clicking a visible link.
In React Router, this is useful when navigation depends on logic rather than a static UI link. Common examples include:
- redirecting after a successful login
- moving to a details page after selecting an item from a dropdown
- sending users away from a protected page if they are not authenticated
- navigating after a form is submitted
The main idea is simple:
Linkis for navigation initiated by the user clicking a link- programmatic navigation is for navigation initiated by code
In older React Router versions, developers often accessed the router through this.context or used mixins like Navigation. That worked because React passed router information down through context, which is a mechanism for making values available to deeply nested components without passing them manually through props.
In modern React Router, the preferred approach is to use APIs like:
useNavigate()in function components- history-based navigation patterns in older versions
- route rendering patterns such as redirects when state changes
Why this matters in real programming:
- it keeps UI and routing in sync
- it lets business logic control where users go next
- it avoids awkward workarounds like simulating link clicks
- it makes flows like authentication, onboarding, and filtering much easier to implement
Mental Model
Think of your app like a building with many rooms.
- A
Linkis like a labeled hallway sign that a person can click to go to another room. - Programmatic navigation is like a staff member escorting the user to a room based on what just happened.
For example:
- if the user picks “Profile” from a dropdown, your code escorts them to
/profile - if login succeeds, your code escorts them to
/dashboard - if access is denied, your code escorts them to
/login
this.context in older React is like a building-wide internal communication system. Instead of every parent component manually handing routing tools down through props, React Router made those tools available through context so child components could access them.
Syntax and Examples
Modern React Router: useNavigate
In current React Router versions, programmatic navigation is usually done with useNavigate().
import { useNavigate } from 'react-router-dom';
function PageSelector() {
const navigate = useNavigate();
function handleChange(event) {
const value = event.target.value;
navigate(value);
}
return (
<select onChange={handleChange}>
<option value="/">Home</option>
<option value="/profile">Profile</option>
<option value="/settings">Settings</option>
</select>
);
}
Step by Step Execution
Consider this example:
import { useNavigate } from 'react-router-dom';
function CategorySelect() {
const navigate = useNavigate();
function handleChange(event) {
const category = event.target.value;
navigate(`/products/${category}`);
}
return (
<select onChange={handleChange}>
<option value="books">Books</option>
<option value="games">Games</option>
<option value="music">Music</option>
</select>
);
}
Step by step
- The component renders a
<select>element.
Real World Use Cases
Programmatic navigation is common in many real applications.
After form submission
if (formIsValid) {
navigate('/thank-you');
}
Use this after users submit contact forms, checkout forms, or account setup forms.
After login or logout
if (loggedIn) {
navigate('/dashboard');
}
Apps often send users to a dashboard after login and back to the login page after logout.
Dropdown-based page changes
navigate(`/country/${selectedCountry}`);
Useful for dashboards, reports, language selection, or category filtering.
Access control
if (!user) {
navigate('/login');
}
Protected pages often redirect unauthenticated users.
Multi-step flows
For onboarding, checkout, or surveys, code often decides the next page based on prior answers.
Error handling
If an item is missing or invalid, apps may redirect users to a not-found or fallback route.
Real Codebase Usage
In real projects, developers usually do not navigate randomly from many places. They use repeatable patterns.
Event-driven navigation
Navigation often happens inside handlers:
onClickonSubmitonChange- async callbacks after API responses
Guard clauses
A common pattern is to leave early when something is missing.
function handleCheckout() {
if (!cartItems.length) {
navigate('/cart');
return;
}
navigate('/payment');
}
This keeps control flow clear.
Redirect after validation
async function handleSave() {
const result = await saveProfile();
if (!result.success) return;
navigate('/profile/success');
}
Common Mistakes
1. Using old APIs in modern React Router
You may see examples like this:
this.context.transitionTo('/home');
or:
this.context.router.push('/home');
These belong to older React Router versions. In modern apps, prefer:
const navigate = useNavigate();
navigate('/home');
2. Confusing browser navigation with router navigation
Beginners sometimes do this:
window.location.href = '/profile';
This causes a full page reload. In a React Router app, use:
navigate('/profile');
3. Calling navigation immediately during render
Broken example:
Comparisons
Link vs programmatic navigation
| Approach | Best for | Example | Trigger |
|---|---|---|---|
Link | Normal visible navigation | <Link to="/about">About</Link> | User clicks a link |
| Programmatic navigation | Logic-based routing | navigate('/about') | Code decides when to navigate |
Old vs modern React Router navigation
| Approach | Typical API | Version style | Notes |
|---|---|---|---|
| Old context-based |
Cheat Sheet
Quick reference
Modern function components
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/profile');
navigate('/dashboard', { replace: true });
Navigate from a dropdown
function handleChange(event) {
navigate(event.target.value);
}
Build dynamic routes
navigate(`/products/${id}`);
Older class component style
this.props.history.push('/profile');
Legacy patterns you may see
...();
..();
FAQ
How do I navigate programmatically in React Router?
In modern React Router, use useNavigate() and call navigate('/path') inside an event handler or other logic.
What is this.context in older React Router examples?
this.context was an older React feature used to pass shared values, including router tools, through the component tree without manually passing props.
Can I navigate without using Link?
Yes. Link is only one way to navigate. You can also navigate in code after a dropdown change, button click, API result, or validation check.
Do I still need mixins for navigation?
No. Mixins are an old React pattern. Modern React Router uses hooks such as useNavigate(), and older class-based apps often used history props instead.
What is the difference between push and replace?
push adds a new browser history entry. replace overwrites the current one.
Should I use window.location.href in a React Router app?
Usually no. It reloads the page. Prefer router navigation for smooth client-side route changes.
Mini Project
Description
Build a simple page selector component that navigates users to different sections of an app when they choose an option from a dropdown. This demonstrates programmatic navigation in response to user input instead of relying on clickable links.
Goal
Create a dropdown that sends the user to a different route using React Router code-based navigation.
Requirements
- Create at least three routes such as Home, Profile, and Settings.
- Add a dropdown component that contains route values.
- Navigate to the selected route when the dropdown value changes.
- Show a different component on each route.
- Use React Router navigation instead of
window.location.
Keep learning
Related questions
Deep Cloning Objects in JavaScript: Methods, Trade-offs, and Best Practices
Learn how to deep clone objects in JavaScript, compare structuredClone, JSON methods, and recursive approaches with examples.
Get Screen, Page, and Browser Window Size in JavaScript
Learn how to get screen size, viewport size, page size, and scroll position in JavaScript across major browsers with clear examples.
How JavaScript Closures Work: A Beginner-Friendly Guide
Learn how JavaScript closures work with simple explanations, examples, common mistakes, and practical use cases for real code.