Introducción

Como ya sabemos, React es una librería pensada para la creación de Interfaces de Usuario, por lo que es necesario complementarla con otras librerías cuando necesitamos realizar cualquier otro tipo de acción. El armado de Interfaces de Usuario, a menudo, implica mostrar una ruta para que el usuario sepa dónde se encuentra dentro de nuestra aplicación. En el ecosistema de librerías de React nos encontramos con react-router-dom creada específicamente para este tipo de tareas.

Cómo funciona

Al incorporar react-router-dom (npm install react-router-dom) a nuestro proyecto tendremos acceso, entre otras cosas, a cuatro elementos que nos permiten armar la navegación de nuestra aplicación
  • BrowserRouter - Este componente utiliza el concepto de la composición (en este post vas a encontrar información al respecto) para almacenar las distintas rutas que crearemos. Todos los Componentes que hacen a nuestra navegación deben ser hijos de este.
    BrowserRouter, además, se encarga de comunicarse con el servidor para indicarle la ruta que se está usando. Esto permite que podamos solicitar acceso a información almacenada en el mismo.
    Para que BrowserRouter funcione correctamente, entonces, es necesario contar con acceso al back-end para hacer lo que se conoce como fallback de servidor. Es decir, configurar la respuesta que recibimos cuando pasamos la ruta.
    Existe otro Componente llamado HashRouter cuyo trabajo también es almacenar las rutas. La diferencia es que este nunca se comunica con el servidor.
    En cualquier caso, lo fundamental es asegurarse que todos los Componentes de nuestra navegación sean Hijos de BrowserRouter/HashRouter

  • Routes - El Componente Routes es el encargado de cambiar la vista cuando cambia la ruta. Este es otro Componente que depende de la composición, pero, en lugar de almacenar rutas, accede a las rutas almacenadas por BrowserRouter (o HashRouter) y, si la ruta que estamos queriendo acceder es una de ellas, se encarga de generar el correspondiente renderizado de la vista. 

  • Route - Con este Componente podremos indicar qué vista corresponde a qué ruta. Para lograrlo debemos pasarle dos props: path y element

    • path - En esta prop debemos declarar la ruta que el usuario debe escribir para acceder a la vista. Por ejemplo, si queremos que se muestre una vista cuando el usuario escriba www.miweb.com/contacto, debemos pasar la prop path="/contacto"
    • element - Con esta prop le indicaremos al Componente Routes qué Componente debe renderizar cuando el usuario acceda a la ruta declarada en la prop path

    El Componente Route debe ser Hijo del Componente Routes


  • Link - Podemos pensar en el Componente Link de la misma forma en que pensamos a los elementos a de HTML. Es decir, Link es el Componente que nos permite darle al usuario la posibilidad de ir hacia alguna ruta de nuestra aplicación al hacer clic en dicho elemento. Para lograrlo necesitamos pasarle en la prop to la ruta a la que queremos redireccionar al usuario (igual que si usáramos el atributo href de los elementos a). Existe una versión de este Componente que nos permite agregar estilos para la ruta activa llamado NavLink.
    Link (o NavLink) deben ser utilizados dentro de los Componentes que se renderizan en la vista
Ejemplo de armado de rutas con react-router-dom

Ejemplo de uso de Link/NavLink


Armado del Componente para la ruta

Más arriba, en el ejemplo de trabajo con react-router-dom, se puede distinguir cómo al Componente Route se le pasa un único Componente que será el encargado de generar la vista para esa ruta. El problema, claro está, es que una vista es producto de la conjunción de varios elementos. Incluso, habrá algunos que se repetirán en las distintas vistas. 

Existen dos soluciones para este problema. Una, la más antigua, implica crear un HOC para el Layout. La otra, posible a partir de la versión 6, es utilizar el Componente Outlet.

En el post ReactJS: Higher Order Component vs. Hook Personalizado cómo crear un HOC. En el caso del armado del Layout (ubicación de los distintos elementos de una vista) son una excelente respuesta. La idea, entonces, es crear un HOC para el Layout y, a partir de este, crear el Componente a renderizarse en la ruta correspondiente.

Por otra parte, el Componente Outlet (que toma la misma lógica de los HOC) permite indicar qué Componente mostrar según la ruta y agregarle el Layout correspondiente. Para ello, es necesario crear rutas hijas. Es decir, debemos crear un Componente Route que tenga un path (por ejemplo, path="/") y envolver con ese otros Componentes Route.  Tener en cuenta que los Componentes Route envueltos tendrán su ruta armada a partir del Componente Route que los envuelve.

A continuación te dejo un ejemplo de armado de rutas utilizando las dos opciones.


Manejo Avanzado de Rutas

Redirección en Componentes

Existen ocasiones en las que necesitamos ser nosotros quienes controlemos a qué ruta debemos enviar al usuario. Para esos casos existen el Componente Navigate y el Hook useNavigate.

El Componente Navigate solo podemos usarlo dentro del return de los elementos, lo que nos obliga a armar una lógica de redirección atada al renderizado del Componente.

El Hook useNavigate, en cambio, nos permite crear una función de redirección que se puede aplicar en cualquier parte de nuestro Componente. Por lo tanto, es posible generar una redirección como consecuencia, por ejemplo, de la ejecución de un Evento.

Paso de Parámetros

La obtención de un Parámetro pasado por ruta consta de dos partes. Primero debemos declarar la ruta que soporte el parámetro; segundo debemos recuperar dicho parámetro en el Componente que lo necesitamos. Para eso necesitamos el Hook useParams.

Con useParams tendremos acceso a un objeto que almacena todos los parámetros que pasamos en la ruta. La clave del objeto será la que pasemos cuando creamos la ruta que soporta el Parámetro

Rutas privadas

Las rutas privadas nos permiten impedir el acceso a ciertas partes de la aplicación si el usuario no está autorizado. Una forma sencilla de crearlas es la combinación de lógica condicional y el Componente Navigate.

Para lograr una ruta privada crearemos un Componente que contendrá la lógica condicional. Este Componente es el que usaremos para como element del Componente Route. Cuando la lógica condicional retorne false, usaremos el Component Navigate para mostrar una pantalla de error; en cambio, cuando retorne true, redireccionaremos al Componente que tiene la vista protegida.