CodeForge

React 19 de Cero a Experto / Routing

Layouts anidados con Outlet

Teoría20 min20 XP

Casi toda app tiene partes que se repiten entre pantallas: un encabezado, un menú lateral, un pie. Sería absurdo repetir ese menú en cada componente de ruta. React Router lo resuelve con las RUTAS ANIDADAS y <Outlet>: defines un layout compartido una vez, y las rutas hijas se renderizan DENTRO de él, en el hueco que marca el <Outlet>. Hoy dominas la estructura de una app real: layouts que persisten mientras el contenido cambia.

El marco que no se mueve

Anidar rutas y el Outlet

Anidas <Route> dentro de otro: el padre define el layout, los hijos las vistas. El layout pone un <Outlet> donde quiere que aparezca el hijo:

layout.tsx
import { Routes, Route, Outlet, NavLink } from "react-router-dom";

// El LAYOUT: estructura compartida + <Outlet> donde va el hijo
function LayoutApp() {
return (
  <div style={{ display: "flex" }}>
    <aside>
      <NavLink to="/gastos">Gastos</NavLink>
      <NavLink to="/perfil">Perfil</NavLink>
    </aside>
    <main>
      <Outlet /> {/* aquí se renderiza la ruta hija según la URL */}
    </main>
  </div>
);
}

function App() {
return (
  <Routes>
    <Route path="/" element={<LayoutApp />}>
      {/* estas rutas se renderizan DENTRO del <Outlet> del layout */}
      <Route index element={<Inicio />} />          {/* "/" por defecto */}
      <Route path="gastos" element={<Gastos />} />   {/* "/gastos" */}
      <Route path="perfil" element={<Perfil />} />   {/* "/perfil" */}
    </Route>
  </Routes>
);
}

El <Route path="/" element={<LayoutApp />}> es el padre: su element (el layout con el <Outlet>) envuelve a todos los hijos. Cuando la URL es /gastos, el router renderiza LayoutApp y, dentro de su <Outlet>, <Gastos>. El menú y la estructura NO se re-montan al navegar entre /gastos y /perfil —solo cambia lo que hay en el <Outlet>—. Fíjate que los path hijos NO llevan / inicial ("gastos", no "/gastos"): son relativos al padre.

Rutas índice y anidamiento profundo

¿Qué hace <Outlet> y por qué usar rutas anidadas para un layout compartido?

Mini-reto

Diseña la estructura de una app de gastos con layout: 1) un <Route path="/"> con un LayoutApp que tenga un menú lateral y un <Outlet>; 2) dentro, una ruta index (bienvenida), gastos y perfil; 3) bonus: dentro de gastos, anida un segundo layout con sub-pestañas resumen e historial, cada uno con su <Outlet>. Dibuja (en papel) qué se renderiza para la URL /gastos/historial —qué layouts se apilan—.

Qué sigue

Ya estructuras la app en layouts. Pero una ruta no es solo una vista: casi siempre necesita DATOS (cargar el gasto antes de mostrarlo). React Router puede coordinar eso con LOADERS (datos antes de renderizar) y ACTIONS (mutaciones desde formularios de ruta). La próxima lección abre esa capa de datos integrada en el enrutado.