En el artículo anterior configuramos nuestro Router y definimos las rutas. Nuestra aplicación ya sabe qué pintar según la URL.
Sin embargo, tenemos un problema (serio) de usabilidad: no tenemos botones para navegar 😊. Y si usamos enlaces HTML tradicionales (<a href="...">), rompemos el comportamiento de la SPA.
En este artículo vamos a aprender a movernos por nuestra aplicación de la forma correcta, utilizando los componentes Link y NavLink.
La etiqueta <a>
En el desarrollo web tradicional, para ir de una página a otra usamos:
<a href="/contacto">Ir a Contacto</a>
¿Por qué está prohibido en React? Porque la etiqueta <a> tiene un comportamiento nativo inevitable: le dice al navegador que haga una petición nueva al servidor.
Cuando esto ocurre:
El navegador descarga el HTML de nuevo.
Se reinicia todo el JavaScript.
Se pierde todo el Estado de React (useState, useContext, etc).
Para solucionar esto, React Router nos proporciona el componente <Link>.
El componente <Link>
Visualmente, <Link> se renderiza como una etiqueta <a> en el DOM final (para mantener la accesibilidad y el SEO).
Pero internamente, intercepta el clic. Hace un event.preventDefault() para evitar la recarga y utiliza la History API del navegador para cambiar la URL manualmente.
Sustituimos el atributo href por la prop to.
import { Link } from 'react-router';
function Navbar() {
return (
<nav>
{/* ✅ FORMA CORRECTA */}
<Link to="/">Inicio</Link>
<Link to="/about">Sobre Nosotros</Link>
<Link to="/contacto">Contacto</Link>
</nav>
);
}
Al pulsar estos enlaces, la URL cambiará instantáneamente y React Router renderizará el componente correspondiente sin pestañear.
El componente <NavLink>
Ahora bien, en una barra de navegación es un estándar de UX resaltar la página en la que estamos actualmente. Queremos que el botón de “Inicio” salga de otro color si estamos en la Home.
Podríamos hacerlo manualmente comprobando la URL, pero React Router nos da un componente específico para esto: <NavLink>.
<NavLink> es una versión especial de <Link> que sabe si su prop to coincide con la URL actual del navegador.
La prop className como función
En las versiones modernas de React Router, la prop className de un NavLink acepta una función. Esta función recibe un objeto con la propiedad isActive.
import { NavLink } from 'react-router';
import './Navbar.css'; // Asumimos una clase .active { color: red; }
function Navbar() {
return (
<nav>
<NavLink
to="/"
className={({ isActive }) => isActive ? "menu-item active" : "menu-item"}
>
Inicio
</NavLink>
<NavLink
to="/about"
className={({ isActive }) => isActive ? "menu-item active" : "menu-item"}
>
Sobre Nosotros
</NavLink>
</nav>
);
}
Rutas relativas vs absolutas
Un detalle técnico importante sobre la prop to.
Ruta Absoluta (Empieza por /)
<Link to="/contacto"> siempre llevará a dominio.com/contacto, estemos donde estemos.
Ruta Relativa (NO empieza por /)
Se añade a la URL actual. Si estamos en /usuarios y renderizamos <Link to="detalles">, el navegador irá a /usuarios/detalles.
Generalmente, en el menú principal usaréis rutas absolutas.
Ejemplo completo: Layout con navegación
Vamos a integrar todo lo que hemos aprendido (Rutas + Navegación) en un layout común.
// src/App.jsx
import { Routes, Route, NavLink } from 'react-router';
import Home from './pages/Home';
import About from './pages/About';
function App() {
// Función auxiliar para estilos
const getLinkClass = ({ isActive }) =>
isActive ? "font-bold text-blue-500" : "text-gray-500";
return (
<div>
{/* 1. Navegación Persistente */}
<header className="p-4 border-b">
<nav className="flex gap-4">
<NavLink to="/" className={getLinkClass}>Inicio</NavLink>
<NavLink to="/about" className={getLinkClass}>About</NavLink>
</nav>
</header>
{/* 2. Contenido Dinámico */}
<main className="p-4">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<h2>404 Not Found</h2>} />
</Routes>
</main>
</div>
);
}
