React Router. Configuración de las rutas
Simplifica la creación de la rutas y su configuración cuando trabajas con React Router

English version: https://medium.com/@ger86/react-router-route-configuration-968f4aac7fab
Hoy quiero hablaros de una forma bastante interesante de organizar la rutas de React Router para que no tengamos que recurrir a escribir una a una las rutas de nuestra aplicación mediante componentes <Route>
, lo cual termina en gigantescas estructuras del tipo:
<Switch>
<Route ...>
<Route ...>
<Route ...>
...
🤯🤯🤯
</Switch>
Además, esto nos servirá como punto de partida para añadir nueva lógica a las mismas como comprobación de roles o separar sus layouts en función de un parámetro que determinemos.
Este artículo está basado de la idea propuesta en la documentación de la librería React Router cuyo ejemplo podéis consultar en este enlace.
Para completar el artículo al final del mismo tenéis un enlace al CodeSandbox que he creado para que podáis jugar con él.
Así que, sin entretenernos más, ¡vamos a verlo!
Punto de partida
Lo primero que haremos será partir de una aplicación que tenga la típica estructura de rutas que os comentaba antes:

Básicamente en la aplicación tenemos 3 rutas definidas cada una asociada a un componente y un componente Menu
encargado de pintar los enlaces para navegar entre cada una de ellas.
Sin embargo, conforme nuestra aplicación crezca el número de rutas que puede albergar el componente <Switch>
puede ser excesivo, por lo que la idea de este artículo es mostrar cómo podemos simplificar la generación de este componente.
Definiendo un objeto ruta
Lo primero que vamos a hacer va a ser abstraer el concepto de ruta en un objeto, de modo que podamos posteriormente automatizar su generación dentro del componente Switch
.
Dado que estamos trabajando con una aplicación muy sencilla, un objeto que defina una ruta tendrá dos propiedades:
component
, para identificar el componente asociado a la ruta,path
, es decir, elstring
para acceder a la ruta.
Dicho esto, crearemos un archivo routes.js
(yo lo suelo crear dentro de la carpeta config/routing
donde definamos cada una de las rutas de nuestra aplicación:

De este modo, definiremos cada ruta especificando sus dos propiedades y exportaremos un array con todas las que hayamos definido.
Además, de cara a especificar la propiedad component
de cada ruta, estoy accediendo al objeto views
, importado desde el archivo components/views/index.js
y que tiene el siguiente aspecto:

Empleando nuestros objetos ruta
Una vez que ya tenemos definidas las rutas de nuestra aplicación, ahora bastará con emplear el array que estamos exportando de nuestro archivo routes.js
dentro del componente Switch
de modo que podamos recorrerlo para crear automatícamente los componentes Route
:

A partir de ahora añadir nuevas rutas a nuestra aplicación es tan sencillo como crear su componente y añadirlo su correspondiente objeto dentro del archivo routes
.
Bien, bien. Pero eso no es todo, a continuación veremos algunas cosas interesantes que podemos hacer.
😉 Consejo
De cara a no tener los paths
de las rutas escritos a fuego en la aplicación, suelo definirlos en el archivo config/routing/paths
como constantes, de modo que no tenga que escribir el string
cada vez que quiero redirigir a la ruta:

De modo que en la creación de nuestros objetos para cada ruta y sus correspondientes enlaces dentro del componente Menu
sean los que usemos:

Especificando rutas privadas de forma sencilla
Ahora que hemos abstraído nuestras rutas, realizar comprobaciones para acceder a ellas es muy sencillo.
Por ejemplo, supongamos que queremos especificar dentro de nuestra aplicación rutas públicas y rutas privadas, de modo que para acceder a una ruta privada tengamos que haber iniciado sesión.
Lo primero que haremos será crear su correspondiente componente, al cual yo llamaré PrivateView
en el proyecto cuyo CodeSandbox os recuerdo que tenéis al final del artículo.
A continuación, vamos a vitaminar nuestras rutas para añadirlas una propiedad que indique si dicha ruta es o no privada:

Y crearemos nuestro propio componente Route
a partir del componente Route
de la librería React Router para que se encargue de realizar la comprobación de si una ruta es o no privada:

Básicamente, en vez de usar la propiedad component
del componente Router
, lo que hago es aprovechar su propiedad render
para realizar la comprobación de si la ruta es o no accesible.
La utilidad userIsLoggedIn
es una función que devuelve true
o false
en función del estado en que se encuentre el usuario que visita la página.
Ahora ya sólo basta con emplear este componente dentro de nuestro archivo App.js
en vez del proporcionado por React Router y ya tendremos nuestras rutas protegidas:

React Lazy
Aunque el mismo resultado podemos obtenerlo declarando las rutas de forma normal. esta configuración de rutas funciona igual de bien con React.lazy y Suspense para permitirnos aligerar el tamaño de nuestro bundle principal, sirviendo los componentes asociados a la ruta bajo demanda. Para ello basta tan sólo con modificar nuestro archivo components/views/index.js
para que emplee React.lazy
:

y rodear la definición de nuestras rutas en el archivo App.js
con Suspense
.
Conclusiones
Como veis, este sistema puede ser muy adecuado para aplicaciones grandes donde haya múltiples rutas y cuyos “layouts” difieran en función del usuario o el tipo de contenido.
Todo esto es posible abstraerlo mediante la definición de rutas como si fueran objetos, de modo que podamos agrupar toda la lógica y no sea necesario repetirla una y otra vez a medida que añadimos nuevas rutas y componentes.
Si queréis ver el proyecto completo funcionando os dejo el enlace a un CodeSandbox para que trasteéis con él:
Además, seguro que encontráis alguna que otra pega a este sistema, así que si os apetece, dejar vuestra opinión en los comentarios para discutirla y así seguir aprendiendo.
¿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: 👇👇👇