React Router: Como usar as rotas no React? - Parte III
Na parte 2 desse módulo aprendemos a como utilizar os parâmetros da URL, para possibilitar uma navegação ainda mais fluida e completa dentro da nossa aplicação. Nessa terceira parte do artigo iremos aprender a como tratar erros e por consequência enviar um feedback, isto é, uma resposta para o usuário de que ocorreu algum erro dentro da nossa aplicação. Para isso, iremos dar continuidade ao projeto que estamos utilizando desde a parte 1 do artigo, se você chegou aqui de paraquedas e quer pegar essa explicação desde o início acesse esse link
Qual é a importância de lidar com erros?
Lidar com erros de maneira eficaz é fundamental para criar uma experiência de usuário positiva e funcional em qualquer aplicação ou sistema. A importância de tratar erros está relacionada a diversos aspectos que impactam diretamente a usabilidade, a confiabilidade e a credibilidade da aplicação. Vamos explorar algumas razões pelas quais é essencial lidar com erros de forma adequada:
Experiência do Usuário (UX) Melhorada: Erros não tratados ou mensagens de erro confusas podem frustrar os usuários e dificultar o uso da aplicação. Quando os usuários não entendem o que deu errado e por que, eles podem se sentir desencorajados a continuar usando o aplicativo. Por outro lado, tratar erros de maneira clara e fornecer feedback compreensível pode melhorar a experiência do usuário, permitindo que eles compreendam o problema e saibam como resolvê-lo. Nós não queremos que o usuário veja um erro desse tipo, seria um susto para ele:
Identificação e Resolução de Problemas: Ao lidar com erros de forma estruturada, a equipe de desenvolvimento (que somos nós, desenvolvedores) pode coletar informações úteis sobre o que deu errado e por quê. Isso facilita a identificação e a resolução de problemas, permitindo que os desenvolvedores abordem as questões subjacentes e melhorem a qualidade do aplicativo ao longo do tempo.
Navegação Fluida: Lidar com erros na URL, como mencionado na introdução, é um exemplo de como tratar erros pode melhorar a navegação fluida na aplicação. Se a aplicação não consegue lidar com URLs inválidas ou malformadas, os usuários podem ficar presos em páginas de erro ou redirecionamentos inesperados, o que prejudica a usabilidade.
Exemplificando erros: No desenvolvimento da nossa aplicação estamos usando um contexto baseado em um site que possui alguns produtos, que nesse caso são jogos. Voltando para a parte 2 do artigo, nós utilizamos o useParams() para usar os parâmetros da URL, mas vamos supor que o usuário tentou acessar um produto que não existe dentro do nosso banco de dados: o arquivo database.json. Isso dará um erro na nossa aplicação, sem dúvidas. Para acessar o que seria mostrado para o usuário, na URL da aplicação, ao invés de acessarmos um valor válido de ID (que no caso vai de 1 até 5) vamos passar um valor inválido que seja maior do que 5 e menor do que 1. Veja só, irei passar o valor 1000:
Como você pode observar, o produto 1000 evidentemente não existe na lista dos nossos produtos e como consequência disso a nossa aplicação dar um erro! Inclusive, o próprio React nos dar uma dica: “💿 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.” Ele avisa para nós desenvolvedores que nós poderíamos criar uma tela de erro que possuísse um melhor UX do que a tela de erro padrão do React (que é imagem acima), usando ErrorBoundary ou errorElement.
Então é isso que aprenderemos nesse artigo!
Configurando mecanismos de erros
Dentro da pasta src, iremos criar duas novas pastas separadas: loaders e errorBoundaries.
Explicando o loader: o loader é uma propriedade disponível dentro dos caminhos das rotas da nossa aplicação, e elas servem exatamente para carregar algum conteúdo: seja ele uma requisição à API, carregar informações de um banco de dados e entre outros. O loader é uma função que deve retornar alguma coisa, algum carregamento.
Explicando errorBoundary: o errorBoundary é um elemento que vai ficar “observando” se determinada rota vai ocorrer algum tipo de erro, e se caso aconteça irá ser tratado de alguma forma de acordo com o que foi projetado.
As pastas devem estar assim:
Agora dentro da pasta loaders iremos criar um arquivo chamado products. Isso seria o arquivo responsável por fazer alguma requisição e retornar algo, por exemplo. No nosso exemplo, a “requisição” será feita para o database.json retornar o produto que queremos acessar a partir do parâmetro da função da rota que estamos usando o loader (que nesse caso é o productId). Por esse motivo, usamos a prop params que já é uma prop disponível em todo loader, que vai usar o parâmetro específico da rota em que está inserida. Dentro desse arquivo estará assim:
Agora vamos retornar o produto específico que queremos, igual fizemos no arquivo Product.jsx anteriormente em outro artigo. Iremos procurar esse produto baseado no seu parâmetro e retorná-lo:
No arquivo Product.jsx podemos deixá-lo assim:
Agora, dentro do arquivo router.jsx é necessário incluir o nosso loader:
Agora falta a última etapa para concluir o carregamento do loader, que é usá-lo. Se formos até o arquivo Product.jsx vamos ver que não retornamos nada para product:
Isso está acontecendo justamente porque ainda não usamos o loader, que é o responsável por carregar nossa “requisição”, que são os produtos. Para isso vamos usar um hook chamado userLoaderData(), que vai basicamente capturar o retorno da função do loader que criamos! Logo, o arquivo Product.jsx ficará assim:
OBSERVAÇÃO IMPORTANTE: no arquivo product.js, que está dentro da pasta loaders, altere o nome da função para loadProduct! Se você não fizer isso haverá conflito com o database.json:
Usando o errorElement
Após terminarmos todas as configurações do loader acima, vamos começar a tratar e visualizar de fato os erros. Antes de prosseguir, vale ressaltar que para que possamos utilizar o errorElement de maneira completa e eficiente é necessária a configuração de um loader para a rota que queremos tratar erros, logo é um requisito obrigatório essa configuração que fizemos anteriormente.
Dentro da pasta errorBoundaries, vamos criar um componente chamado ProductBoundary, e dentro dele deve ter o seguinte conteúdo:
const error = useRouterError();
A linha de código acima é um outro hook do React Router DOM, que vai retornar o erro mais próximo da rota em que ele estar inserido. E por meio desse erro, podemos tratá-los de acordo com a necessidade.
if (isRouteErrorResponse(error)) {
}
A linha de código acima verifica se o erro que foi retornado é um erro de resposta de rota:
404 - Não Encontrado: O servidor não encontrou o recurso solicitado. Isso é frequentemente usado para representar que uma rota não corresponde a nenhuma das rotas definidas na aplicação.
401 - Não Autorizado: O acesso ao recurso é negado devido à falta de autenticação válida ou à autenticação inválida. Isso pode ser usado para roteamento quando um usuário não tem permissão para acessar determinada rota.
403 - Proibido: O servidor entendeu a solicitação, mas se recusa a autorizá-la. Diferente do 401, aqui o usuário está autenticado, mas não possui as permissões necessárias.
500 - Erro Interno do Servidor: Indica que o servidor encontrou uma situação com a qual não sabe lidar. Pode ser usado para indicar um erro interno ao renderizar uma rota.
502 - Bad Gateway: Indica que um servidor, enquanto atuando como gateway ou proxy, recebeu uma resposta inválida do servidor upstream que estava acessando para atender a solicitação.
503 - Serviço Indisponível: O servidor não está pronto para manipular a solicitação. Isso pode ocorrer, por exemplo, quando o servidor está sobrecarregado ou em manutenção.
504 - Gateway Timeout: O servidor, enquanto atuando como gateway ou proxy, não recebeu uma resposta oportuna do servidor upstream ou algum outro servidor necessário para lidar com a solicitação.
Essa verificação decorrente desse Hook, possibilita acessar uma propriedade do objeto pela qual ele retorna chamada: status. Dessa forma, podemos tratar os erros com uma precisão muito melhor:
Agora basta usarmos o errorElement passando o componente que criamos, dentro do arquivo router.jsx:
Agora, no navegador podemos tentar acessar algum produto que não existe, e veremos que está tudo funcionando:
Analisando os outros tipos de erros de resposta de rota
Dentro do nosso arquivo loader chamado product.js vamos lançar um erro de resposta personalizado para que possamos analisar e verificar se todos os erros realmente estão funcionando. Para isso, seu arquivo deve analisar se caso o produto não exista, lançar um erro de resposta de forma manual:
}
No navegador, a mensagem de erro mudará pois lançamos um erro do tipo 404 e mensagem aparecerá de acordo com o que definimos no switch case:
Para verificar os outros erros basta mudar o status do erro lançado. Não esqueça de atualizar a página no seu navegador para que veja o novo erro!
Conclusão
Em conclusão, esta terceira parte do artigo aprofundou nosso conhecimento sobre a importância de tratar erros de forma adequada em aplicações. Como vimos ao longo do artigo, lidar com erros não é apenas uma questão técnica, mas também desempenha um papel fundamental na criação de uma experiência de usuário positiva e funcional.
Através da abordagem cuidadosa de tratamento de erros, conseguimos compreender como a usabilidade, a confiabilidade e a credibilidade de uma aplicação podem ser diretamente impactadas. Ao proporcionar mensagens de erro claras e informativas, podemos evitar frustrações por parte dos usuários e incentivá-los a continuar utilizando a aplicação, mesmo diante de adversidades.
Assim como um sistema bem projetado é capaz de minimizar erros técnicos, um tratamento de erros eficaz pode minimizar as consequências negativas de eventuais problemas. Ao investir tempo e esforço na implementação de estratégias de feedback e comunicação de erros, estamos contribuindo para a construção de produtos de qualidade e para a satisfação duradoura dos usuários.
Portanto, ao prosseguir com o projeto que acompanhamos desde a primeira parte deste artigo, convido você a aplicar os conhecimentos adquiridos aqui. Implemente uma abordagem de tratamento de erros que não apenas solucione problemas, mas também ofereça uma experiência que inspire confiança e facilite a resolução de dificuldades por parte dos usuários.
Agradeço por ter me acompanhado nesta jornada de aprendizado e aprimoramento. Com as bases sólidas estabelecidas nas três partes deste artigo, você está bem equipado para criar aplicações mais robustas, eficazes e amigáveis com React Router DOM. Lembre-se sempre de que a busca pela excelência no tratamento de erros é um passo essencial para o sucesso de qualquer projeto de desenvolvimento.
Se você deseja revisitar alguma parte deste artigo, pode encontrar os links para as partes anteriores abaixo:
Continuarei a explorar temas relevantes como este para enriquecer seu conhecimento e habilidades no desenvolvimento de software. Fique atento para mais conteúdo envolvente e educativo.
Até a próxima jornada!
A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.