Routing options in react


When building web apps with React, especially single-page applications (SPAs), routing is a key part of the experience. You might be tempted to reach for the classic <a> tag to handle navigation — after all, it’s been around forever. But while that works in static websites, it's not ideal for React apps.
In this post, we’ll break down why using an anchor tag in React is a bad idea for internal routing, and show you better alternatives that maintain performance, preserve state, and provide a seamless user experience.
<a href="/route">At first glance, using an anchor tag in React seems straightforward:
<a href="/about">About</a>It’s simple. It works. But there’s a catch.
When you use an anchor tag like that in a React app, it triggers a full-page reload. That means:
This defeats the purpose of a Single Page Application, where route changes should be handled client-side for a faster, smoother experience.
Great catch — that context is super helpful for beginners. Here's the improved version of that section with the missing setup instructions included:
When building SPAs with React, React Router is the go-to solution for handling navigation. It enables smooth, client-side transitions between pages — no full-page reloads — keeping your app fast and responsive.
To get started, install the necessary packages using your package manager of choice:
npm install react-router-dom
# or
yarn add react-router-dom🔧 Note: This installs
react-router-dom, which includes everything you need for web-based routing. For native apps, you'd usereact-router-nativeinstead.
<Link> Instead of <a>Instead of this:
<a href="/about">About</a>Use this:
import { Link } from 'react-router-dom';
<Link to="/about">About</Link>The <Link> component is built for client-side routing in React. It updates the browser’s URL and triggers a component render — all without refreshing the browser or losing app state.
Sometimes you need to change the route based on user actions like clicking a button or completing a form.
useNavigate() (React Router v6+)import { useNavigate } from 'react-router-dom';
const MyComponent = () => {
const navigate = useNavigate();
const handleClick = () => {
navigate('/dashboard');
};
return <button onClick={handleClick}>Go to Dashboard</button>;
};useHistory() (React Router v5)In older versions:
import { useHistory } from 'react-router-dom';
const MyComponent = () => {
const history = useHistory();
const handleClick = () => {
history.push('/dashboard');
};
return <button onClick={handleClick}>Go to Dashboard</button>;
};window.location.hrefThis is a traditional method for navigation that causes a full-page reload.
window.location.href = '/about';Use this only when redirecting to external websites or in very specific cases where a full reload is intended.
| Method | SPA-Friendly | Version | Pros | Cons |
|---|---|---|---|---|
<a href="/route"> | ❌ | All | Simple, built-in | Full page reload, breaks SPA behavior |
<Link to="/route"> | ✅ | All | SPA navigation, no reload | Requires React Router |
<NavLink> | ✅ | All | Active link styling | Same as Link with styling extras |
useNavigate() | ✅ | v6+ | Easy programmatic navigation | React Router required |
useHistory() | ✅ | v5 | Programmatic navigation in v5 | Deprecated in v6 |
window.location.href | ❌ | All | Good for external links | Causes full reload |
| Use Case | Recommended Method | SPA-Friendly | Version |
|---|---|---|---|
| Internal navigation via click | <Link> or <NavLink> | ✅ | All |
| Style active nav links | <NavLink> | ✅ | All |
| Navigate after an action (v6+) | useNavigate() | ✅ | v6+ |
| Navigate after an action (v5) | useHistory() | ✅ | v5 |
| External website / file download | <a> or window.location.href | ❌ | All |
Changing routes in React isn’t just about linking to a different page — it’s about maintaining a seamless user experience. While anchor tags have their place, they don't belong in your React SPA for internal navigation.
Stick to tools like <Link>, <NavLink>, useNavigate(), and useHistory() for a faster, cleaner, and more React-friendly approach to routing.
Your users (and your app’s performance) will thank you.

Shadows disappearing in your Threlte or Three.js scene? It’s a frustum issue. Learn how to visualize the shadow box and fix clipping instantly with this guide.

What happens when you create a DocType in Frappe? We break down the .json, .js, and .py files generated by the framework and how to use them.

Confused by Shopify's lack of a database? 🤯 Learn how Shopify stores your theme data, from simple Settings to complex Metafields. Perfect for devs moving from WP/Laravel.