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)ojo
useParams 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: true
navigate('/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()clave
Lee los parámetros dinámicos de la URL (:id, :slug…). Devuelve un objeto con strings.
useNavigate()clave
Navega 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' })