Enrutamiento
Una app de React renderiza un árbol de componentes en un documento HTML. Los sitios reales tienen una página de inicio, una página de información, una página de detalles, cada una con su propia URL. El enrutamiento es donde estos dos hechos se encuentran: la URL decide qué componentes se renderizan, y navegar en la app actualiza la URL. React Router es la librería que usan la mayoría de las apps de React para esto, y el curso le dedica una sección completa, construyendo una app de renta de vans llamada VanLife en el camino. Este capítulo cubre las piezas principales; las rutas anidadas y los parámetros de ruta se construyen sobre ellas.
Enrutamiento del lado del cliente: MPA vs SPA
En una aplicación tradicional multipágina (MPA), cada navegación es un viaje de ida y vuelta. El navegador solicita /about al servidor, el servidor arma una página HTML y la devuelve, y el navegador descarta la página actual para cargar la nueva. Ese cambio de página completa se ve como un parpadeo inconfundible en cada clic.
Una aplicación de una sola página (SPA) carga un documento una sola vez. El nombre es un poco engañoso: el sitio todavía puede tener muchas páginas desde la perspectiva del usuario. Lo que es único es el documento. Después de la carga inicial, la app de React en sí decide qué mostrar para cada URL. Navegar a /about intercambia componentes dentro de la app en ejecución, sin que se solicite un nuevo documento y sin parpadeo. Si una vista necesita datos frescos, la app obtiene JSON en segundo plano y actualiza en su lugar, el patrón cubierto en Obteniendo datos.
El enrutamiento del lado del cliente es el mecanismo que hace que esto funcione: una librería observa la URL, intercepta la navegación y renderiza los componentes coincidentes en lugar de permitir que el navegador recargue. Hay un premio real en mantener el documento vivo. Una carga de página completa borra todo el estado de React; mantenerse dentro de un documento significa que tu estado sobrevive a cada navegación.
Nota de versión
El curso enseña React Router 6. La versión 7 fusionó React Router con Remix y consolidó los paquetes, por lo que react-router es la ruta de importación actual. react-router-dom sobrevive en v7 como una re-exportación y es el paquete que usan v6 y el curso, por eso cada ejemplo en este manual importa desde él; la versión 8 la descartó, así que una instalación nueva importa estos componentes desde react-router.
React Router documenta tres modos: declarativo, los componentes BrowserRouter y Route que cubre este capítulo; data, que empareja createBrowserRouter con loaders y actions; y framework, un plugin de Vite que añade módulos de ruta tipados, code splitting y renderizado en servidor. Los nombres de componentes y hooks en este capítulo no cambian entre esas versiones.
BrowserRouter, Routes y Route
Tres componentes definen una configuración básica: BrowserRouter envuelve la app y habilita el enrutamiento, Routes contiene tus definiciones de rutas, y cada Route mapea una ruta a un elemento.
import { BrowserRouter, Routes, Route } from 'react-router-dom'
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
)
}Internamente, BrowserRouter es un proveedor de contexto. Envolver la app con él da a cada componente de abajo acceso a las herramientas del router, por eso se coloca en la parte superior. Algunos proyectos lo renombran en la importación (import { BrowserRouter as Router }) ya que el nombre completo es algo largo.
Cada Route toma dos props. path es la parte de la URL después del dominio: / para la página de inicio, /about para la página de información. element es el JSX a renderizar cuando la URL coincida con esa ruta, escrito como un elemento real, <Home /> en lugar de Home. Cuando la URL es /about, React Router renderiza <About /> donde se encuentra el componente Routes; todo lo que está fuera de Routes se renderiza en cada página.
Si visitas una ruta sin una coincidencia y nada se renderiza en absoluto. Ese problema se soluciona con la ruta catch-all de abajo.
Link: navegar sin recarga de página
La forma HTML de moverse entre páginas es una etiqueta de anclaje, y es exactamente lo incorrecto para una SPA: hacer clic en un <a href="/about"> desencadena una carga de página completa, que descarta la app en ejecución y cada pieza de estado en ella. La respuesta de React Router es el componente Link.
import { Link } from 'react-router-dom'
function Header() {
return (
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
)
}Link toma un prop to en lugar de href, y se lee como el inglés: un enlace a la siguiente ruta. En el navegador sigue renderizando una etiqueta de anclaje real, así que los lectores de pantalla, los menús de clic derecho y tus selectores CSS ven un <a> ordinario. La diferencia está en el controlador de clic: React Router intercepta el clic, actualiza la URL e intercambia los componentes renderizados, todo sin recargar el documento. Un contador en diez se mantiene en diez mientras te mueves entre páginas. Dentro de una app de React Router, la navegación interna siempre pasa por Link; los anclajes simples son para URLs externas.
NavLink y estilos de enlace activo
Las barras de navegación generalmente resaltan la página en la que te encuentras actualmente. NavLink existe exactamente para esto: se comporta como Link, excepto que sus props className y style pueden tomar una función en lugar de un valor simple. React Router llama esa función con un objeto que contiene un booleano isActive, verdadero cuando la ruta del enlace coincide con la URL actual. Este es el patrón de render props, cubierto en Render props, aplicado a un prop que no es children.
import { NavLink } from 'react-router-dom'
function Header() {
return (
<nav>
<NavLink
to="/about"
className={({ isActive }) => isActive ? 'active-link' : ''}
>
About
</NavLink>
</nav>
)
}Lo que la función devuelve se convierte en el nombre de la clase, así que la clase active-link se aplica solo mientras /about es la ruta actual, y tu CSS maneja el resto. El prop style funciona de la misma manera con un objeto de estilo en línea:
const activeStyles = { fontWeight: 'bold', textDecoration: 'underline' }
<NavLink
to="/about"
style={({ isActive }) => isActive ? activeStyles : null}
>
About
</NavLink>Usar nombre de clase o estilo en línea es una decisión de la convención del equipo; ambos son completamente soportados, así que sigue lo que el proyecto ya hace.
Una ruta catch-all para 404
Los usuarios aterrizan en rutas que no existen: un enlace desactualizado, un error tipográfico, una referencia rota de otra persona. Sin un respaldo, React Router no renderiza nada allí. La solución es una ruta catch-all, a veces llamada ruta splat, cuya ruta es un único asterisco.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<NotFound />} />
</Routes>path="*" coincide con cualquier cosa que ninguna otra ruta reclame, muy como un selector universal en CSS. Un componente NotFound típico empareja un mensaje corto con un Link de regreso a la página de inicio. El orden en la lista no importa: React Router 6 califica cada ruta contra la URL y elige la mejor coincidencia, así que el catch-all solo gana cuando nada más específico lo hace. Colocarlo al final es convención y legibilidad antes que necesidad.
Envuelve tu app en BrowserRouter, lista tus páginas como componentes Route dentro de Routes, y cada path obtiene su propio element a renderizar.
Usa Link en lugar de una etiqueta de anclaje para que hacer clic mantenga la app en ejecución, y añade una ruta path="*" para que los visitantes que escriban mal una URL vean una página amigable en lugar de una pantalla en blanco.
Siguiente: Rutas anidadas y layouts, donde las rutas ganan chrome compartido y las rutas dentro de rutas.

