React Router: ¿Cómo usar las rutas en React? - Parte III
En la parte 2 de este módulo aprendimos cómo utilizar los parámetros de la URL para permitir una navegación más fluida y completa dentro de nuestra aplicación. En esta tercera parte del artículo, aprenderemos cómo manejar errores y, como consecuencia, enviar retroalimentación al usuario, es decir, una respuesta que le indique que ocurrió algún error dentro de nuestra aplicación. Para esto, continuaremos con el proyecto que hemos estado usando desde la parte 1 del artículo. Si llegaste aquí sin haber leído las primeras partes y quieres comenzar desde el inicio, puedes acceder a este enlace
¿Cuál es la importancia de manejar los errores?
Manejar los errores de manera efectiva es fundamental para crear una experiencia de usuario positiva y funcional en cualquier aplicación o sistema. La importancia de tratar errores está relacionada con diversos aspectos que impactan directamente la usabilidad, confiabilidad y credibilidad de la aplicación. A continuación, exploraremos algunas razones por las que es esencial gestionar los errores adecuadamente:
Mejorar la Experiencia del Usuario (UX): Los errores no manejados o los mensajes de error confusos pueden frustrar a los usuarios y dificultar el uso de la aplicación. Cuando los usuarios no entienden qué salió mal ni por qué, pueden sentirse desmotivados a seguir utilizando la aplicación. En cambio, gestionar los errores de manera clara y proporcionar retroalimentación comprensible mejora la experiencia del usuario, permitiéndoles entender el problema y saber cómo resolverlo. No queremos que el usuario vea un error de este tipo, ya que podría ser confuso o alarmante para él:
Identificación y Resolución de Problemas: Al manejar los errores de manera estructurada, el equipo de desarrollo (es decir, nosotros como desarrolladores) puede recopilar información útil sobre lo que salió mal y por qué. Esto facilita la identificación y resolución de problemas, permitiendo que los desarrolladores aborden los problemas subyacentes y mejoren la calidad de la aplicación con el tiempo.
Navegación Fluida: Gestionar errores en la URL, como se mencionó en la introducción, es un ejemplo de cómo tratar errores puede mejorar la navegación fluida en la aplicación. Si la aplicación no logra manejar URLs inválidas o mal formadas, los usuarios pueden quedarse atrapados en páginas de error o redirecciones inesperadas, lo que perjudica la usabilidad.
Ejemplificando errores: En el desarrollo de nuestra aplicación estamos utilizando un contexto basado en un sitio que tiene algunos productos, que en este caso son juegos. Retomando la parte 2 del artículo, usamos useParams() para utilizar los parámetros de la URL, pero supongamos que el usuario intenta acceder a un producto que no existe en nuestra base de datos, el archivo database.json. Esto, sin duda, generará un error en nuestra aplicación. Para simular lo que vería el usuario en la URL de la aplicación, en lugar de acceder a un valor de ID válido (que en este caso va del 1 al 5), vamos a pasar un valor inválido, como uno mayor a 5 o menor a 1. Por ejemplo, usaremos el valor 1000:
Como puedes observar, el producto 1000 evidentemente no existe en nuestra lista de productos y, como resultado, nuestra aplicación generará un error. Incluso, React nos da una recomendación: “💿 Hey developer 👋
You can provide a way better UX than this when your app throws errors by providing your own ErrorBoundary or errorElement prop on your route.” Nos sugiere a nosotros, los desarrolladores, que creemos una pantalla de error con mejor UX que la pantalla de error predeterminada de React (que es la de la imagen de arriba) utilizando ErrorBoundary ou errorElement.
¡Eso es lo que aprenderemos en este artículo!
Configurando mecanismos de errores
Dentro de la carpeta src, crearemos dos nuevas carpetas separadas: loaders y errorBoundaries.
Explicando el loader: el loader es una propiedad disponible en las rutas de nuestra aplicación y se utiliza para cargar algún contenido, ya sea una solicitud a la API, cargar información de una base de datos, entre otros. El loader es una función que debe retornar algún tipo de carga de datos.
Explicando el errorBoundary: el errorBoundary es un elemento que “observa” si una ruta específica va a generar algún tipo de error, y, en caso de que ocurra, este se manejará de acuerdo con lo planeado en su configuración.
Las carpetas deberían verse así:
Ahora, dentro de la carpeta loaders crearemos un archivo llamado products. Este archivo será el responsable de hacer una solicitud y retornar algún dato. En nuestro ejemplo, la “solicitud” se hará al archivo database.json para retornar el producto que queremos acceder a partir del parámetro en la función de la ruta que utiliza el loader (en este caso, productId). Por eso, usamos la prop params que ya está disponible en todos los loaders y utilizará el parámetro específico de la ruta donde se encuentra. Dentro de este archivo, el código se verá así:
Ahora vamos a retornar el producto específico que queremos, igual que lo hicimos en el archivo Product.jsx en un artículo anterior. Buscaremos este producto basándonos en su parámetro y lo retornaremos:
En el archivo Product.jsx podemos dejarlo así:
Ahora, dentro del archivo router.jsx es necesario incluir nuestro loader:
Queda la última etapa para concluir el cargado del loader, que es utilizarlo. Si vamos al archivo Product.jsx veremos que no hemos retornado nada para product:
Esto sucede porque aún no usamos el loader, que es el responsable de cargar nuestra “solicitud”, es decir, los productos. Para solucionarlo, usaremos un hook llamado userLoaderData(), que básicamente capturará el retorno de la función del loader que creamos. Entonces, el archivo Product.jsx quedará así:
NOTA IMPORTANTE: en el archivo product.js, dentro de la carpeta loaders, cambia el nombre de la función a loadProduct! Si no haces esto, habrá un conflicto con database.json:
Usando el errorElement
Después de terminar todas las configuraciones del loader anteriores, comenzaremos a manejar y visualizar los errores. Es importante mencionar que, para utilizar el errorElement de manera completa y eficiente, es necesario haber configurado un loader para la ruta en la que queremos manejar los errores. Por lo tanto, la configuración previa que realizamos es obligatoria.
Dentro de la carpeta errorBoundaries, crearemos un componente llamado ProductBoundary, y dentro de él deberá tener el siguiente contenido:
const error = useRouterError();
La línea de código anterior es otro hook de React Router DOM, que va a retornar el error más cercano de la ruta en la que está insertado. A partir de este error, podemos manejarlos según nuestras necesidades.
if (isRouteErrorResponse(error)) {
}
Esta línea de código verifica si el error que fue retornado es un error de respuesta de la ruta:
404 - No Encontrado: El servidor no encontró el recurso solicitado. Esto se utiliza frecuentemente para indicar que una ruta no coincide con ninguna de las rutas definidas en la aplicación.
401 - No Autorizado: El acceso al recurso es denegado debido a una falta de autenticación válida o a una autenticación inválida. Esto puede usarse para redirigir cuando un usuario no tiene permisos para acceder a una ruta determinada.
403 - Prohibido: El servidor entendió la solicitud, pero se rehúsa a autorizarla. A diferencia del 401, aquí el usuario está autenticado, pero no tiene los permisos necesarios.
500 - Error Interno del Servidor: Indica que el servidor encontró una situación que no sabe cómo manejar. Puede usarse para indicar un error interno al renderizar una ruta.
502 - Bad Gateway: Indica que un servidor, actuando como gateway o proxy, recibió una respuesta inválida del servidor de origen al que intentaba acceder para responder la solicitud.
503 - Servicio No Disponible: El servidor no está listo para manejar la solicitud, posiblemente porque está sobrecargado o en mantenimiento.
504 - Gateway Timeout: El servidor, actuando como gateway o proxy, no recibió una respuesta a tiempo del servidor de origen o de otro servidor necesario para procesar la solicitud.
Esta verificación derivada de este hook permite acceder a una propiedad del objeto que retorna llamada: status. De esta forma, podemos manejar los errores con mucha mayor precisión:
Ahora solo debemos usar el errorElement pasando el componente que creamos en el archivo router.jsx:
En el navegador, podemos intentar acceder a un producto que no existe y veremos que todo funciona correctamente:
Analizando otros tipos de errores de respuesta de ruta
Dentro de nuestro archivo loader llamado product.js, lanzaremos un error de respuesta personalizado para analizar y verificar que todos los errores funcionan adecuadamente. Para ello, el archivo debe analizar si el producto no existe y, en ese caso, lanzar manualmente un error de respuesta:
}
En el navegador, el mensaje de error cambiará ya que lanzamos un error de tipo 404, y la respuesta aparecerá según lo definido en el switch case:
Para verificar otros errores, simplemente cambia el estado del error lanzado. ¡No olvides actualizar la página en tu navegador para ver el nuevo error!
Conclusión
En conclusión, esta tercera parte del artículo profundizó nuestro conocimiento sobre la importancia de manejar los errores de manera adecuada en aplicaciones. Como vimos a lo largo del artículo, tratar errores no es solo una cuestión técnica, sino que también desempeña un papel fundamental en la creación de una experiencia de usuario positiva y funcional.
A través de un enfoque cuidadoso en el manejo de errores, pudimos comprender cómo la usabilidad, confiabilidad y credibilidad de una aplicación pueden verse impactadas directamente. Al proporcionar mensajes de error claros e informativos, podemos evitar frustraciones por parte de los usuarios y motivarlos a seguir utilizando la aplicación, incluso frente a adversidades.
Así como un sistema bien diseñado es capaz de minimizar errores técnicos, un tratamiento eficaz de errores puede reducir las consecuencias negativas de posibles problemas. Al invertir tiempo y esfuerzo en la implementación de estrategias de retroalimentación y comunicación de errores, estamos contribuyendo a la construcción de productos de calidad y a la satisfacción duradera de los usuarios.
Por lo tanto, al continuar con el proyecto que hemos seguido desde la primera parte de este artículo, te invito a aplicar los conocimientos adquiridos aquí. Implementa un enfoque de manejo de errores que no solo resuelva problemas, sino que también ofrezca una experiencia que inspire confianza y facilite la resolución de dificultades por parte de los usuarios.
Gracias por haberme acompañado en esta jornada de aprendizaje y mejora. Con las bases sólidas establecidas en las tres partes de este artículo, estás bien preparado para crear aplicaciones más robustas, eficaces y amigables con React Router DOM. Recuerda siempre que buscar la excelencia en el tratamiento de errores es un paso esencial para el éxito de cualquier proyecto de desarrollo.
Si deseas repasar alguna parte de este artículo, puedes encontrar los enlaces a las partes anteriores aquí:
Continuaré explorando temas relevantes como este para enriquecer tu conocimiento y habilidades en el desarrollo de software. Mantente atento para más contenido interesante y educativo.
¡Hasta la próxima aventura!
Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.