Configurar React Router, crear rutas y navegar con Link y NavLink.
El problema que resuelve
Hasta ahora tus apps de React viven en una sola pantalla. En cuanto necesitas "una página de detalle", "una sección de contacto" o simplemente que el botón atrás del navegador funcione, aparece el problema: React por sí solo no sabe nada de URLs.
Podrías resolverlo con estado (const [pantalla, setPantalla] = useState("home")) y funcionaría… hasta que un usuario quiera compartir un link, recargar la página o usar el botón atrás. Ahí se rompe: la URL nunca cambió, así que no hay nada que compartir ni a dónde volver.
React Router hace que la URL sea parte del estado de tu app. Cada vista tiene su dirección, el historial del navegador funciona, y los links se pueden copiar y compartir. Eso es lo que convierte una demo en una aplicación.
SPA: navegar sin recargar
Una SPA (Single Page Application) carga el HTML una sola vez y luego cambia el contenido con JavaScript. La diferencia con un sitio tradicional:
- Sitio multi-página: cada click pide un HTML nuevo al servidor. La pantalla parpadea y se pierde todo el estado de la app.
- SPA con Router: el click intercepta la navegación, cambia la URL sin ir al servidor y monta el componente correspondiente. Instantáneo y sin perder el estado que quieras conservar.
De ahí sale la regla más importante de esta clase, y el error que más vas a ver en código generado:
🚨 Dentro de una SPA nunca uses
<a href>para navegar entre tus propias rutas. El<a>recarga la página entera: pierdes el estado, la app se reinicia y el usuario ve el parpadeo que justamente querías evitar. Para rutas internas se usa<Link>; el<a>queda reservado para enlaces externos.
El setup: tres capas
React Router se arma en tres niveles, y confundirlos es el motivo del 90% de los errores iniciales:
BrowserRouter— envuelve toda la app, una sola vez, enmain.jsx. Es quien escucha los cambios de URL. Si lo olvidas, cualquier<Link>truena con "useNavigate() may be used only in the context of a Router".Routes+Route— el mapa: qué componente corresponde a qué dirección.Routeselige una sola ruta, la que mejor coincide.Link/NavLink— los disparadores de navegación dentro de tus componentes.
Los tres snippets de abajo muestran exactamente esas tres capas, en ese orden.
Link vs NavLink
Ambos navegan igual; la diferencia es que NavLink sabe si él mismo está activo:
jsx1<NavLink 2 to="/about" 3 className={({ isActive }) => (isActive ? "activo" : "")} 4> 5 Acerca 6</NavLink>
NavLink le pasa isActive a tu función de clase (o de estilo) para que marques visualmente la sección actual. Úsalo en la navbar; para el resto de los enlaces, Link basta y es más simple.
Layouts con Outlet
Si tu navbar y tu footer se repiten en todas las páginas, no los copies en cada componente. Se declara un layout que contiene lo común y un hueco donde React Router inyecta la ruta hija:
jsx1function Layout() { 2 return ( 3 <> 4 <Navbar /> 5 <main> 6 <Outlet /> {/* aquí se monta la ruta hija */} 7 </main> 8 <Footer /> 9 </> 10 ); 11} 12 13<Routes> 14 <Route path="/" element={<Layout />}> 15 <Route index element={<Home />} /> 16 <Route path="about" element={<About />} /> 17 </Route> 18</Routes>
Dos detalles que confunden al principio: las rutas hijas se escriben sin la barra inicial (about, no /about, porque se concatenan al padre), y index es la que se muestra cuando la URL coincide exactamente con el padre.
Errores comunes
| Síntoma | Causa |
|---|---|
| La app parpadea y pierde el estado al navegar | Usaste <a href> en vez de <Link> |
| "useNavigate may be used only in the context of a Router" | Falta BrowserRouter envolviendo la app |
| Al recargar una ruta directa sale 404 | El servidor no está configurado para SPA (en Vercel se resuelve solo; en otros hosts hay que redirigir todo a index.html) |
| La navbar no marca la sección activa | Usaste Link donde querías NavLink |
En tu proyecto integrador
Este es el momento en que tu proyecto deja de ser una pantalla y se vuelve una app. Antes de la siguiente sesión, define qué rutas necesita: normalmente una lista, un detalle, y una o dos secciones fijas. Ese mapa de rutas es lo que vas a defender.
Ejemplos de Código
3 ejemplos
BrowserRouter
1import React from "react";
2import ReactDOM from "react-dom/client";
3import { BrowserRouter } from "react-router-dom";
4import App from "./App";
5
6ReactDOM.createRoot(document.getElementById("root")).render(
7 <React.StrictMode>
8 <BrowserRouter>
9 <App />
10 </BrowserRouter>
11 </React.StrictMode>
12);Definir rutas
1import { Routes, Route } from "react-router-dom";
2import Home from "./pages/Home";
3import About from "./pages/About";
4import Contact from "./pages/Contact";
5
6function App() {
7 return (
8 <Routes>
9 <Route path="/" element={<Home />} />
10 <Route path="/about" element={<About />} />
11 <Route path="/contact" element={<Contact />} />
12 </Routes>
13 );
14}Navegación con NavLink
1import { NavLink } from "react-router-dom";
2
3function Navbar() {
4 return (
5 <nav>
6 <NavLink to="/" className={({ isActive }) => (isActive ? "active" : "")}
7 >
8 Inicio
9 </NavLink>
10 <NavLink to="/about">Acerca</NavLink>
11 <NavLink to="/contact">Contacto</NavLink>
12 </nav>
13 );
14}Recursos
3 recursos disponibles
¡Hora de Practicar!
Práctica guiada - Menú de navegación
Práctica
Crear un layout con Navbar y 3 páginas navegables.
Desafío de Código
Ejercicios - Rutas y links
Ejercicios
(1) Ruta de error, (2) layout con Outlet, (3) estilos activos con NavLink.