React. Novedades de React Router 6
Descubre las principales novedades que traerá la librería React Router
React Router es una de las librerías más usadas cuando trabajamos en React y necesitamos gestionar la navegación de nuestra aplicación. De hecho y si os soy sincero desconozco si existen otras alternativas ya que tanto en los proyectos en los que me he integrado como en aquellos que he desarrollado desde cero ha sido la única que he usado cuando he tenido que gestionar rutas.
Pese a que su curva de aprendizaje es algo elevada (especialmente en el momento en que pasas a hacer cosas rebuscadas) y la documentación podría ser algo más extensa (especialmente teniendo en cuenta la cantidad de características que ofrece), no es raro que su versatilidad y potencia la hayan posicionado en el lugar en el que se encuentra.
La versión 5 de React Router incorporó por fin los hooks para dar soporte al nuevo paradigma de React y dentro de pocos meses quedará liberada la versión 6 que trae importantes cambios. De ahí que me haya animado a escribir este artículo para resumir los principales que veremos incorporados.
¡Vamos allá!
⚠️ Pero antes… una pequeña advertencia
Si algo ha caracterizado a React Router es que a menudo las nuevas versiones rompen características antiguas lo cual hace complicado actualizar la librería sin tener que reescribir algunas partes. Por eso, en el momento en que te plantees usar esta versión (todavía se encuentra en beta) revisa bien toda aquella funcionalidad que te tocará actualizar.
Nuevo componente Routes
El componente Switch
de versiones anteriores que permitía discriminar entre rutas en función del path visitado va a ser reemplazado por el componente Routes
.
De este modo, todas las rutas que definamos dentro de este componente mediante <Route path...>
así como los enlaces que generemos mediante el componente <Link to...>
serán relativos a la ruta padre donde estén definidos.
La idea según la documentación es facilitar que una aplicación pueda verse como distintas partes independientes, cada una de ellas viviendo dentro de una ruta:

En el ejemplo, todos los Link
definidos dentro del componente “Products” son relativos a la ruta products/
de modo que por ejemplo el componente <Link to="/iphone" ...>
generará <a href="/products/iphone" ...>
.
Lo mismo sucederá para las rutas definidas dentro del componente “Products” por medio del componente Routes
: todas ellas irán bajo el path /products
.
El componente Outlet
Además, ha aparecido un nuevo componente llamado Outlet
en el caso en que queramos llevar la declaración de rutas a un único lugar pero queramos definir un “layout” para cada grupo de rutas:

En este caso, estamos agrupando las rutas de “/products” sobre el componente Products
que cuando se “renderea” pinta una barra de navegación con enlaces a productos junto con el componente <Outlet />
, donde se alojarán las rutas hijas definidas, pintando aquella que haga “match” con el “path” visitado (bien ProductsList
o bien Product
.
Definición de rutas como objetos
En un artículo anterior os hablé de como podíamos trabajar con React Router de modo que las rutas pudiéramos definirlas como objetos en vez de declararlas una a una:
Bien, pues esta forma de declarar las rutas ya está 100% integrada en React Router por medio del hook useRoutes
:

Como veis seguimos recurriendo al componente <Outlet />
para renderear las rutas hijas dentro del componente <Products />
junto con el layout de esa “mini aplicación” dentro de la aplicación principal.
❗️Según la documentación (y si no la he entendido bien) esta forma de declarar las rutas nos obliga a renderear el componente <App>
dentro de un componente BrowserRouter
declarado por fuera, a diferencia del ejemplo anterior. Esto se debe a que useRoutes
debe estar definida dentro de un contexto creado por BrowserRoute
:
We removed the <BrowserRouter> element from App because the useRoutes hook needs to be in the context of a <BrowserRouter> element. This is a common pattern with React Router apps that are rendered in different environments. To render an <App>, you’ll need to wrap it in your own <BrowserRouter> element.
Integración con la API Suspense de React
Esta nueva versión de React Router estará integrada con la futura API Suspense de React:
Esto se traduce en que el hook useHistory
será reemplazado por el hook useNavigate
para aquellos momentos en los que necesitemos navegar imperativamente por la aplicación (por ejemplo, tras un envío de un formulario).
¿Y para qué puede resultar útil esta característica? En una aplicación integrada con la futura API Suspense de React, React Router será capaz de detectar si la aplicación está suspendida, es decir, cargando datos. Esto supondrá que cualquier push
en el historial será convertido en un replace.
En la documentación de esta nueva versión ponen un ejemplo que ilustra muy bien esta característica. Supongamos una SPA con varios enlaces en la que el usuario hace clic en un enlace que se suspende porque necesita cargar datos y a continuación hace clic en otro enlace yendo a una nueva página. En esta situación, React Router omitirá automáticamente la primera navegación del historial del navegador porque esa página nunca se cargó.
Tamaño del bundle
Finalmente, parece ser que esta nueva versión de React Router pesará un 70% menos lo cual supone un importante avance para aquellas aplicaciones que necesiten estar muy optimizadas en cuanto a rendimiento.
Conclusiones
Como veis esta nueva versión de React Router trae interesantes novedades que cambiarán la forma en que estructuramos y definimos las rutas de nuestra aplicación. Para mí el cambio más importante es la introducción de esa nueva forma de pensar que supone ver los conjuntos de rutas como mini aplicaciones. Muy interesante.
¿Quieres recibir más artículos como este?
Si te ha gustado este artículo te animo a que te suscribas a la newsletter que envío cada domingo con publicaciones similares a esta y más contenido recomendado: 👇👇👇