Porque não usar NgRx
Bom, eu amo o Angular (uso ele desde a versão 2) e acompanhei todas as versões até a versão atual (que no momento que escrevo esse artigo é a v10). Já trabalhei com os mais variados tipos de projetos com Angular e ele sempre foi o meu framework frontend favorito por vários motivos, mas especialmente porque ele é escrito nativamente em TypeScript.
Dito isso, eu nunca senti necessidade de um gerenciador de estados no Angular, porque considerava que a sua toolkit já tinha ferramentas suficientes para lidar com esse problema.
Foi quando eu entrei em um projeto que usava NgRx. Eu tive que ler muita coisa pra entender o conceito e a arquitetura. A medida que eu ia lendo sobre os componentes do NgRx, mais eu ia tendo certeza de que tudo aquilo não passava de overengineering e que nada fazia sentido. Eu não vi vantagem nenhuma (entretanto vi várias desvantagens) no uso dessa ferramenta. Vários dos problemas que o NgRx se propõe a resolver pode ser resolvido nativamente pelo Angular de forma simples! Essas são as minhas principais birras com o NgRx: Fazer tudo que o angular já faz, só que de um jeito muito mais complicado.
Mas vamos aos fatos: Porque não devemos usar o NgRx?
Complexo, Burocrático e Inútil: Prazer, NgRx!
Pra mim, esse argumento já deveria ser o suficiente para acabar com a discussão. Pra entender as vantagens de usar o NgRx, você primeiro vai ter que entender um problema de front-end que não é relacionado ao Angular!
Inicialmente, com o surgimento de bibliotecas como o React, o gerenciamento de estado e eventos era um problema. Para corrigir esse problema, foi criado uma biblioteca chamada Redux que cuidava exatamente dessa parte. O react-redux teve uma grande adoção e se tornou muito popular.
O NgRx é inspirado na arquitetura do Redux. Entretanto, diferentemente do React, o Angular não tem esse problema! Talvez essa ferramenta seja útil para programadores que estão acostumado com o react-redux trabalharem no Angular, mas acredito que não resolve nenhum problema do Angular.
Porque Complexo?
Supondo que você, caro leitor, não faça a mínima idéia do que seja NgRx. Eu te apresento a idéia e te falo que você precisa saber o que é store, action, reducer, effect, selector, etc. E para entender ainda mais os conceitos, você vai ter que saber o que é pure function, side effects, etc.
Se você se assutou com tudo isso, saiba que você não é o único. Eu também me assustei! É complexo por esse motivo: Você tem que saber de vários conceitos pra começar a mexer com a ferramenta!
Porque Burocrático?
Agora que você entendeu todos os conceitos e a arquitetura do NgRx, vamos meter a mão no código! Vamos realizar uma simples tarefa:
Missão:
- Criar um botão que faz uma chamada HTTP e mostra os dados na tela
Obstáculo:
- NgRx!
Vai criar uma ação? Crie a Action!
Mas a ação não faz nada sem um Reducer. Então crie-o!
<Código do reducer>
Quer o valor de um estado? Opa, não esqueça da Store nem dos Selectors!
Vai fazer uma Requisição HTTP? O NgRx ficará chateado se você não usar o Effects!
Se você assim como eu acha que pra completar a missão só bastava os Services e o HttpClient do Angular, então você entendeu meu ponto! Isso torna a abordagem do NgRx extremamente cansativa e burocrática.
<Código do service + componente>
Porque Inútil?
Essa é a pergunta mais fácil de responder: Porque dá pra resolver todos os problemas que o NgRx resolve só com a arquitetura padrão do Angular!
Se você reparar bem no nome do NgRx, ele é a combinação de duas siglas: Ng (Angular) e Rx (Reactive X). Se a idéia do NgRx era prover ferramenta para trabalhar com a programação reativa dentro do Angular, isso reforça o meu ponto de que ele é totalmente inútil, uma vez que o próprio Angular já tem o RxJS como dependência!
Falo isso porque muitas das coisas que o NgRx implementa é relacionado a Reactive Programming, porém o Angular já é Reativo! Contudo vou explicar isso com exemplos a seguir.
Estados no Angular
E se eu te falar que já existe o conceito de State no Angular? Sim, existe!
Nesse caso, o estado só é valido para esse componente. Sim é verdade, entretanto temos os Services que podem funcionar como um estado global, já que se trata de um singleton, e pode ser injetado em qualquer lugar!
Actions no Angular
Pela própria documentação do NgRx, uma action é:
Actions são um dos pricipais pilares no NgRx. Elas expressam eventos únicos que acontecem ao longo da sua aplicação, de interações do usuário com a página, interações externas via http requests e interações diretas com a API do dispositivo. Esses e demais eventos são denominados Actions.
No angular, temos o Event binding que nos ajuda a lidar com interações do usuário na página e mudanças de estados dos componentes. Para alterações externas não podemos esquecer que o Angular é um framework reativo e usa RxJs, e portanto podemos escutar essas alterações usando os Observables.
Além disso, você mesmo pode criar “Actions” e “Stores” nativamente com Angular, de uma forma muito mais simples! Estruturas como o Subject, BehaviorSubject, ReplaySubject, AsyncSubject eliminam o uso de “Action” e “Stores”.
O problema dos reducers
O Angular é desenhado para ser orientado a objetos, portanto é imporante seguir os princípios do SOLID (Indico a leitura desse artigo).
Para qualquer um que ama estudar Code Smells e Design Patterns como eu, já sente nojo só de olhar um código assim:
Essa abordagem fere completamente o OCP (Open/Closed Principle), pois para cada nova ação, eu tenho que adicionar linhas nesse código.
Além disso, os reducers são totalmente inúteis se usarmos a forma do Angular para alterar estados, que é através dos métodos. Inclusive, essa abordagem é totalmente compatível com as boas práticas de OO, visto que metodos são usados para alterar o estado da classe!
Conclusão
Fontes e recomendações de leitura: