A equipe de desenvolvedores da Pris se dedica diariamente à evolução de nossos softwares, de forma a atender melhor nossos parceiros e clientes. Essa dedicação se dá tanto no aspecto de backend, quanto no de front end. Uma de nossas soluções, o Pris, utiliza o framework web Angular com bibliotecas adicionais para auxiliar o desenvolvimento, a manutenibilidade e a performance do nosso projeto. Uma dessas bibliotecas é o NgRx, responsável por controlar o estado da nossa aplicação de uma maneira estruturada e organizada.
MAS O QUE SIGNIFICA ISSO?
Para alinharmos os conceitos iniciais, é importante explicar: o estado da aplicação é o conjunto de dados que afetam o que você vê na tela. Ao manter dados em componentes e dentro da árvore de componentes ao invés de usar essa estrutura, há uma consequência problemática: podem ser geradas longas cadeias de Inputs e Outputs entre componentes, que podem ser custosas para manutenção. Os dados podem começar a se tornar inconsistentes e a legibilidade do fluxo de dados pode ficar comprometida.
E o que o NgRx faz, junto ao Angular, para resolver esse problema? Ele basicamente controla os dados externamente a essa árvore de componentes e os distribui por meio de Observables.
Para explicar o que são Observables cabe uma analogia: imagine uma linha de transmissão telefônica. Quando alguém atende, a pessoa começa a escutar as palavras que são emitidas na linha. Essa linha de transmissão é o Observable. As palavras são os dados que ele emite. A pessoa é quem se inscreve na linha de transmissão para receber os dados, podendo ser uma componente, um serviço, entre outros.

ESTRUTURA
A estrutura do NgRx é baseada na arquitetura do Redux e faz forte uso da biblioteca de programação assíncrona, RxJS.

Explicando de forma didática:
- O estado da aplicação fica alojado na Store.
- As mudanças de estado são feitas por ações (Actions) do usuário.
- Para aplicar as mudanças requisitadas pela ação (Action), usamos o Reducer.
- O Reducer é responsável por produzir novos estados da aplicação.
- O responsável por passar os dados do estado da aplicação para as componentes é o Selector.
- E, para lidar com chamadas assíncronas externas, utilizamos os Effects.
IMPORTÂNCIA DO USO DE EFFECTS
Os Effects são uma poderosa ferramenta para eliminar vazamento de responsabilidades das componentes.
De forma resumida, ele fica escutando as ações (Actions) emitidas até capturar a ação que ele irá lidar. Depois de lidar com as chamadas externas, ele emite uma nova ação (Action), geralmente, de sucesso ou de erro, de acordo com o resultado da chamada externa.
Sem Effects, dependendo da arquitetura do projeto, sua componente será responsável por:
- Chamar dados da API;
- Lidar com erros de dados vindo da API;
- Alimentar a Store com dados vindos da API.
Quanto mais responsabilidades suas componentes tiverem, mais difícil será a manutenção e a legibilidade do projeto.
Com Effects, sua componente irá apenas escutar os dados/erros vindo da Store. Quem efetivamente irá lidar com a API e com o erro ou o sucesso na requisição é o Effect.
ACTION
API: createAction
Parâmetros:
- Type: descreve a ação que está sendo realizada. O padrão é utilizar colchetes para indicar a origem da ação e a descrição da ação.
- Config: propriedades da ação (metadados adicionais).
REDUCER
API: createReducer
Importante: o Reducer não cria novos estados com o estado atual alterado. Ele constrói um novo estado da aplicação por meio de funções puras (pure functions¹), indo de encontro ao princípio da imutabilidade (immutability²).
Parâmetros:
- initial State: estado inicial
- ons: associação entre ações e mudanças de estado
EFFECTS
API: createEffect
Parâmetros:
- source: função que retorna um observable
SCHEMATICS
O NgRx oferece uma extensão à CLI do Angular para gerar seus recursos por meio dos schematics.
Os arquivos de Effects, Reducer, Store, Actions e Selectors podem não ser intuitivos para serem criados “à mão” e, graças aos Schematics, podemos gerá-los automaticamente.
O padrão para gerar esses recursos é o mesmo da CLI do Angular.
REDUX DEV TOOLS
Para depurar nossa aplicação, utilizamos uma robusta extensão no navegador chamada Redux DevTools. Por meio da interface visual desse, é possível visualizar todo o estado da aplicação, as mudanças no estado da aplicação por Action e, também, navegar entre os estados anteriores da aplicação, graças à imutabilidade dos estados (immutability²).
Para usá-lo, basta adicionar o módulo nos imports do app.module:
API: StoreDevtoolsModule.instrument()
Parâmetros (opcional): https://ngrx.io/guide/store-devtools/config ( )

CONCLUSÃO
Se quiser trocar experiências e conhecimentos sobre Angular, NgRx ou outros temas de TI, basta entrar em contato! Será um prazer para toda a nossa equipe. E caso queira trabalhar conosco, siga nossa página de vagas clicando aqui.
NOTAS
¹pure functions: são funções que sempre quando recebem os mesmos argumentos, retornam a mesma coisa. Para o nosso caso, não podemos alterar nosso estado atual, já que pode acarretar em mudanças no retorno. Benefício: se elas sempre têm o mesmo retorno, elas podem utilizar resultados já calculados para economizar processamento.
²immutability: quando um objeto é criado, não podemos alterá-lo! Para alterá-lo, devemos copiá-lo e, depois, alterar a cópia. Benefício: detecção de mudança rápida (sem imutabilidade, o processamento de comparação deve comparar cada atributo do objeto).
Fonte das imagens:
Imagem 1 - Celestialsys
Imagem 2 - NgRx.io
Imagem 3 - Github