GUÍA COMPLETA DE REACT ROUTER PARA WEB
Introducción a React Router
React Router es la biblioteca más popular y potente para gestionar la navegación en aplicaciones web desarrolladas con React. Permite definir rutas, navegar entre páginas y manejar datos dinámicos de manera eficiente. En esta guía, exploraremos las características esenciales de React Router DOM, la variante diseñada específicamente para aplicaciones web, utilizando el paquete react-router-dom. Cubriremos desde la instalación hasta el uso de hooks avanzados, con ejemplos prácticos para cada concepto.
Instalación de React Router DOM
Para comenzar a usar React Router DOM, el primer paso es instalar el paquete en tu proyecto. Esto se realiza mediante un administrador de paquetes como npm o yarn. La instalación es sencilla y requiere un solo comando.
npm install react-router-dom
Este comando instala la biblioteca necesaria para aplicaciones web. Es importante destacar que existen otras variantes, como React Router Native, diseñada para aplicaciones móviles con React Native, pero en esta guía nos enfocaremos exclusivamente en la versión para web.
Configuración Básica con BrowserRouter
El componente principal para habilitar el enrutamiento es BrowserRouter, que debe envolverse alrededor de la aplicación para que las rutas funcionen correctamente. Es común renombrar BrowserRouter como Router para mayor claridad en el código.
import { BrowserRouter as Router } from "react-router-dom";
function App() {
return <Router>{/* Aquí se definen las rutas */}</Router>;
}
export default App;
El componente BrowserRouter permite declarar rutas como hijos y asegura que cualquier funcionalidad específica de enrutamiento, como el acceso al historial o parámetros de ruta, esté disponible solo dentro de este componente.
Definición de Rutas con Route
El componente Route es el núcleo para definir rutas en la aplicación. Cada ruta requiere al menos dos propiedades: path, que especifica la URL de la ruta, y component o render, que indica qué componente renderizar cuando la URL coincide con el path.
import { BrowserRouter as Router, Route } from "react-router-dom";
function App() {
return (
<Router>
<Route path="/acerca" component={Acerca} />
</Router>
);
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
export default App;
El uso de component es directo, ya que recibe una referencia al componente a renderizar. Alternativamente, render permite lógica condicional para decidir qué renderizar.
import { BrowserRouter as Router, Route } from "react-router-dom";
function App() {
return (
<Router>
<Route path="/" render={() => <Inicio />} />
<Route path="/acerca" component={Acerca} />
</Router>
);
}
function Inicio() {
return <div>Página de inicio</div>;
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
export default App;
También es posible renderizar componentes como hijos de Route, omitiendo component o render.
import { BrowserRouter as Router, Route } from "react-router-dom";
function App() {
return (
<Router>
<Route path="/acerca">
<Acerca />
</Route>
</Router>
);
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
export default App;
Para elementos que deben aparecer en todas las páginas, como una barra de navegación, colócalos dentro de Router pero fuera de las rutas específicas.
import { BrowserRouter as Router, Route } from "react-router-dom";
function App() {
return (
<Router>
<BarraNavegacion />
<Route path="/" component={Inicio} />
<Route path="/acerca" component={Acerca} />
</Router>
);
}
function BarraNavegacion() {
return <nav>Barra de navegación</nav>;
}
function Inicio() {
return <div>Página de inicio</div>;
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
export default App;
Uso del Componente Switch
Cuando defines múltiples rutas, puedes encontrarte con el problema de que varias rutas se rendericen simultáneamente. Por ejemplo, la ruta “/” puede coincidir parcialmente con “/acerca”. Para evitar esto, utiliza el componente Switch, que asegura que solo se renderice la primera ruta que coincida con la URL actual.
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<Router>
<BarraNavegacion />
<Switch>
<Route exact path="/" component={Inicio} />
<Route path="/acerca" component={Acerca} />
</Switch>
</Router>
);
}
function BarraNavegacion() {
return <nav>Barra de navegación</nav>;
}
function Inicio() {
return <div>Página de inicio</div>;
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
export default App;
La propiedad exact en la ruta “/” garantiza que solo coincida con la URL exacta, evitando conflictos con otras rutas. Switch es ideal para aplicaciones con múltiples páginas, ya que asegura que solo una página se muestre a la vez.
Manejo de Rutas 404
Para manejar casos en los que el usuario accede a una URL no definida, crea una ruta comodín con el path definido como “*”. Esta ruta actúa como un captura-todo y puede renderizar un componente para indicar que la página no existe.
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<Router>
<BarraNavegacion />
<Switch>
<Route exact path="/" component={Inicio} />
<Route path="/acerca" component={Acerca} />
<Route path="*" component={NoEncontrado} />
</Switch>
</Router>
);
}
function BarraNavegacion() {
return <nav>Barra de navegación</nav>;
}
function Inicio() {
return <div>Página de inicio</div>;
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
function NoEncontrado() {
return <div>Página no encontrada</div>;
}
export default App;
Esta configuración garantiza que los usuarios reciban una respuesta clara cuando intentan acceder a una página inexistente.
Navegación con Link y NavLink
Para facilitar la navegación, React Router DOM ofrece los componentes Link y NavLink. Link crea enlaces que permiten a los usuarios moverse entre rutas sin recargar la página. La propiedad to especifica la URL de destino.
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
function App() {
return (
<Router>
<BarraNavegacion />
<Switch>
<Route exact path="/" component={Inicio} />
<Route path="/acerca" component={Acerca} />
</Switch>
</Router>
);
}
function BarraNavegacion() {
return (
<nav>
<Link to="/">Inicio</Link>
<Link to="/acerca">Acerca</Link>
</nav>
);
}
function Inicio() {
return <div>Página de inicio</div>;
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
export default App;
NavLink extiende las capacidades de Link al permitir estilos condicionales para la ruta activa mediante las propiedades activeStyle o activeClassName.
import {
BrowserRouter as Router,
Switch,
Route,
NavLink,
} from "react-router-dom";
function App() {
return (
<Router>
<BarraNavegacion />
<Switch>
<Route exact path="/" component={Inicio} />
<Route path="/acerca" component={Acerca} />
</Switch>
</Router>
);
}
function BarraNavegacion() {
return (
<nav>
<NavLink activeStyle={{ fontWeight: "bold", color: "red" }} to="/">
Inicio
</NavLink>
<NavLink activeClassName="activo" to="/acerca">
Acerca
</NavLink>
</nav>
);
}
function Inicio() {
return <div>Página de inicio</div>;
}
function Acerca() {
return <div>Acerca de nosotros</div>;
}
export default App;
La propiedad activeClassName es útil para aplicar estilos reutilizables definidos en hojas de estilo externas, mientras que activeStyle permite estilos en línea.
Redirecciones con Redirect
El componente Redirect es útil para redirigir a los usuarios a otra ruta bajo ciertas condiciones, como en rutas protegidas que requieren autenticación. Por ejemplo, puedes crear un componente RutaPrivada que verifique si un usuario está autenticado antes de renderizar el componente deseado.
import {
BrowserRouter as Router,
Switch,
Route,
Redirect,
} from "react-router-dom";
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Inicio} />
<RutaPrivada path="/oculta" component={Oculta} />
</Switch>
</Router>
);
}
function RutaPrivada({ component: Componente, ...rest }) {
const estaAutenticado = useAuth(); // Hook personalizado para autenticación
return (
<Route
{...rest}
render={(props) =>
estaAutenticado ? (
<Componente {...props} />
) : (
<Redirect to="/" />
)
}
/>
);
}
function Inicio() {
return <div>Página de inicio</div>;
}
function Oculta() {
return <div>Página oculta</div>;
}
export default App;
Este enfoque es ideal para proteger rutas sensibles y garantizar que los usuarios no autenticados sean redirigidos a una página pública, como un formulario de inicio de sesión.
Hook useHistory para Navegación Programática
El hook useHistory permite acceder al objeto de historial y realizar navegación programática. Este hook es útil para redirigir a los usuarios en respuesta a eventos, como después de iniciar sesión.
import { useHistory } from "react-router-dom";
function Acerca() {
const historial = useHistory();
return (
<div>
<h1>Estás en: {historial.location.pathname}</h1>
<button onClick={() => historial.push("/")}>
Ir a la página de inicio
</button>
</div>
);
}
export default Acerca;
El método historial.push agrega una nueva entrada al historial, mientras que historial.replace reemplaza la entrada actual, lo que es útil en casos como cerrar sesión, donde no deseas que el usuario regrese a la página anterior.
Hook useLocation para Datos de Ubicación
El hook useLocation proporciona información sobre la URL actual, como el pathname y parámetros de consulta, sin las capacidades de navegación de useHistory. Es ideal cuando solo necesitas datos de la ubicación actual.
import { useLocation } from "react-router-dom";
function Acerca() {
const ubicacion = useLocation();
return (
<div>
<h1>Estás en: {ubicacion.pathname}</h1>
</div>
);
}
export default Acerca;
Si necesitas tanto datos de ubicación como navegación, utiliza useHistory, ya que incluye la propiedad location.
Rutas Dinámicas con useParams
Las rutas dinámicas permiten manejar URLs con segmentos variables, como identificadores de recursos. Para definir una ruta dinámica, utiliza dos puntos (:) seguidos del nombre del parámetro en el path.
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Inicio} />
<Route path="/blog/:slugEntrada" component={EntradaBlog} />
</Switch>
</Router>
);
}
function Inicio() {
return <div>Página de inicio</div>;
}
function EntradaBlog() {
return <div>Entrada de blog</div>;
}
export default App;
Para acceder al parámetro dinámico, utiliza el hook useParams, que devuelve un objeto con los parámetros de la ruta.
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
function EntradaBlog() {
const [entrada, setEntrada] = useState(null);
const { slugEntrada } = useParams();
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/posts/${slugEntrada}`)
.then((res) => res.json())
.then((data) => setEntrada(data));
}, [slugEntrada]);
if (!entrada) return null;
return (
<div>
<h1>{entrada.title}</h1>
<p>{entrada.body}</p>
</div>
);
}
export default EntradaBlog;
Este ejemplo demuestra cómo usar useParams para obtener el slugEntrada y cargar datos dinámicos desde una API.
Hook useRouteMatch para Coincidencias de Rutas
El hook useRouteMatch permite verificar si la URL actual coincide con un patrón de ruta específico, devolviendo un objeto con información sobre la coincidencia o null si no hay coincidencia.
import { useRouteMatch } from "react-router-dom";
function EntradaBlog() {
const coincide = useRouteMatch("/blog/:slugEntrada");
return (
<div>
{coincide ? (
<h1>Estás en una entrada de blog</h1>
) : (
<h1>No estás en una entrada de blog</h1>
)}
</div>
);
}
export default EntradaBlog;
Este hook es útil para mostrar contenido condicional basado en la ruta actual, como elementos de interfaz específicos para ciertas páginas.
Conclusiones
React Router DOM es una herramienta esencial para gestionar la navegación en aplicaciones web React. Con componentes como BrowserRouter, Route, Switch, Link, NavLink y Redirect, junto con hooks como useHistory, useLocation, useParams y useRouteMatch, puedes construir aplicaciones con navegación fluida y dinámica. Esta guía cubre las funcionalidades clave para implementar un enrutamiento robusto, desde la configuración básica hasta la gestión de rutas dinámicas y redirecciones condicionales. Con estos conocimientos, estás preparado para crear aplicaciones web modernas y escalables con React.