▶ 1. Instalación y Setup
Terminal
# Instalar en tu proyecto Vite
npm install react-router-dom
main.jsx — envolver la app
import { BrowserRouter } from 'react-router-dom' ReactDOM.createRoot(document.getElementById('root')) .render( <BrowserRouter> <App /> </BrowserRouter> )
<BrowserRouter>
clave
Proveedor raíz. Usa la History API del navegador.
Solo debe haber uno por app. Va en
main.jsx.
▶ 2. <Routes> y <Route>
App.jsx — configurar rutas
import { Routes, Route } from 'react-router-dom' function App() { return ( <> <Navbar /> // fuera → siempre visible <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/post/:id" element={<Post />} /> <Route path="*" element={<NotFound />} /> </Routes> <Footer /> // fuera → siempre visible </> ) }
<Routes>
Renderiza solo el primer
<Route>
que coincide con la URL actual.
path="*"clave
Comodín (wildcard). Captura cualquier URL que no
coincidió antes. Siempre va al final.
▶ 3. <Link> y <NavLink>
<a href>
evitar
Recarga la página completa y destruye todo el
estado de React. Nunca lo uses para navegar dentro de la app.
<Link to>
clave
Navega sin recargar. Preserva el estado. Genera
un
<a> en el HTML final pero intercepta el
clic.
Ejemplos
import { Link, NavLink } from 'react-router-dom' // Link básico <Link to="/perfil">Mi Perfil</Link> // Link dinámico con template literal <Link to={`/post/${articulo.id}`}>Leer más</Link> // NavLink: agrega clase "active" automáticamente <NavLink to="/inicio" className={({ isActive }) => isActive ? "text-violet-400 font-bold" : "text-white" } >Inicio</NavLink>
<NavLink>
Igual que
<Link> pero recibe una función en
className con { isActive }. Perfecto
para resaltar el ítem activo del menú.
▶ 4. useParams
useParams()
clave
Lee los segmentos dinámicos de la URL (los que
empiezan con
: en el path). Siempre
devuelve strings.
Ruta configurada en App.jsx
<Route path="/post/:id" element={<PostDetail />} />
PostDetail.jsx — leer el parámetro
import { useParams } from 'react-router-dom' function PostDetail() { const { id } = useParams() // URL /post/42 → id === "42" (string) // Convertir a número si hace falta: const numId = Number(id) return <h1>Post #{id}</h1> }
Number(id)ojouseParams siempre devuelve strings. Si necesitás
comparar con IDs numéricos, convertí con
Number(id).
▶ 5. useNavigate
useNavigate()
clave
Navega de forma programática (desde código, no
desde un clic en un Link). Útil después de un login, submit de
formulario, etc.
Ejemplo — redirigir después de login
import { useNavigate } from 'react-router-dom' function LoginForm() { const navigate = useNavigate() function handleSubmit(e) { e.preventDefault() // ... lógica de login ... navigate('/dashboard') // ir hacia adelante } return <form onSubmit={handleSubmit}>...</form> }
navigate(-1)
Equivale al botón "Atrás" del navegador. Podés usar
cualquier número:
navigate(-2) retrocede 2 páginas.
replace: truenavigate('/ruta', { replace: true }) reemplaza
la entrada actual en el historial, en vez de agregar una nueva.
▶ 6. useLocation
useLocation()
Devuelve el objeto de la ubicación actual. Útil
para saber en qué ruta estás, leer query strings o pasar estado
entre rutas.
Propiedades del objeto location
import { useLocation } from 'react-router-dom' function MiComponente() { const location = useLocation() location.pathname // "/post/42" location.search // "?page=2&sort=date" location.hash // "#seccion-1" location.state // estado pasado con navigate() }
Leer query params (?page=2)
const location = useLocation() const params = new URLSearchParams(location.search) const page = params.get('page') // "2"
▶ 7. Patrones de Rutas
/rutaestática
Coincide exactamente con esa URL.
Ej:
/about, /contacto.
/ruta/:paramdinámica
El
:param captura cualquier segmento.
Ej: /post/:id coincide con /post/1,
/post/hola, etc.
/:a/:b
Múltiples parámetros. Ej:
/cat/:categoria/post/:id. Se leen todos con
useParams().
path="*"al final
Comodín: captura todo lo que no coincidió. Siempre debe ir
como última
<Route>.
Ejemplo con múltiples params
// Route: <Route path="/tienda/:categoria/:id" element={<Producto />} /> // URL: /tienda/ropa/42 const { categoria, id } = useParams() // categoria === "ropa" | id === "42"
▶ 8. Rutas Anidadas + <Outlet>
<Outlet />
avanzado
Marca el lugar donde se renderiza el componente hijo de una ruta
anidada. El componente padre actúa como un "layout".
Configuración en App.jsx
<Routes> <Route path="/dashboard" element={<DashboardLayout />}> // Estas rutas se renderizan DENTRO de DashboardLayout <Route index element={<DashHome />} /> <Route path="perfil" element={<DashPerfil />} /> <Route path="config" element={<DashConfig />} /> </Route> </Routes>
DashboardLayout.jsx — usa <Outlet />
import { Outlet, Link } from 'react-router-dom' function DashboardLayout() { return ( <div className="flex"> <aside> <Link to="perfil">Perfil</Link> <Link to="config">Config</Link> </aside> <main> <Outlet /> // aquí se renderiza la ruta hija </main> </div> ) }
index
La ruta
index es la ruta "por defecto" del padre. Se
activa cuando la URL coincide exactamente con la del padre
(/dashboard).
▶ 9. Resumen de Hooks
useParams()claveLee los parámetros dinámicos de la URL (
:id, :slug…). Devuelve un objeto con strings.useNavigate()claveNavega por código.
navigate('/ruta'), navigate(-1) (atrás), navigate(1) (adelante).useLocation()Objeto con la URL actual:
.pathname, .search, .hash, .state.useSearchParams()Lee y escribe los query params (
?clave=valor). Similar a useState pero sincronizado con la URL.useSearchParams — ejemplo
import { useSearchParams } from 'react-router-dom' const [searchParams, setSearchParams] = useSearchParams() // Leer: URL → /posts?page=3 const page = searchParams.get('page') // "3" // Escribir: cambia la URL a /posts?page=4 setSearchParams({ page: '4' })