Gerenciamento de Estado em Flutter e algumas soluções

Depois de criar uma tela e animar em Flutter, precisamos de mais uma coisa importante: o gerenciamento de estado. Saiba como o Flutter utiliza nativamente essa função e quais opções temos para melhorar essa camada.
Kevin Santos | 1 de setembro de 2020

Depois de criar uma tela e animar em Flutter, precisamos de mais uma coisa importante: o gerenciamento de estado. Entender a importância dele e porque há tantas soluções para isso  no Flutter, também vai te ajudar a escolher o melhor caminho, já que não há uma opção definitiva. Mas antes de entramos nas soluções existentes, vale falar um pouco sobre o que é o gerenciamento de estado num ambiente de Client Side (Front end e Mobile).

O que é gerenciamento de estado em Flutter?

Gerenciamento de estado, ou State Management, se resume a obtenção de dados para transformar  o estado da sua aplicação. Vou explicar melhor.

O Flutter vai ‘desenhar’ a tela e vai tentar fazer isso apenas uma vez para economizar processamento. Para desenhar uma tela de listagem, por exemplo, você irá precisar de informações vindas de algum lugar, seja por api, firebase, entre outros, porém essas informações podem não ser estáticas. Se essas informações mudarem, o Flutter precisa ser notificado que houve uma mudança para poder redesenhar essa parte da tela.

O foco do gerenciamento de estado é como notificar o Flutter sobre o que ele precisa redesenhar e como fazer isso de forma performática, custando pouco processamento.

Nativamente o Flutter já possui um ‘notificador’ chamado Set State, mas às vezes ele pode não ser a melhor opção.

O Set State

Super simples de usar, porém custoso. Esse Set State vem quando você cria um Stateful Widget e é uma função da classe. Quando chamado, ele notifica ao Flutter que aquele Widget deve ser redesenhado porque alguma coisa mudou.

Por exemplo:

gerenciamento_flutter_exemplo.png

Nesse exemplo, que vem por padrão ao criar um projeto Flutter, podemos ver que há um Stateful Widget. Ao pressionar o FloatingActionButton, a função _incrementCounter é chamada, e então o setState é acionado, notificando o Flutter da mudança que por sua vez irá redesenhar o _MyHomePageState por completo.

Fácil de se usar, contudo, nesse caso ele irá não só redesenhar o Widget Text (único que irá de fato mudar de acordo com _counter) mas irá redesenhar todos os Widgets como Scaffold, AppBar, Center, Column, Text e o FloatingActionButton. Isso não é muito performático, pois não precisamos que tudo seja redesenhado, apenas o Text na linha 52.

Por isso, nem a própria equipe do Google recomenda usar esse método para aplicativos de médio a grande porte. Em alguns casos esse método é perfeito por sua simplicidade, em outros pode trazer grande custo ao seu aplicativo.

A solução para o problema

Já que o SetState tem esse problema de performance, a ideia seria disponibilizar para os Widgets, independente da posição deles na árvore de elementos, os dados e notificar para os Widgets da mudança para que o Flutter apenas redesenhe o que for necessário.

Screen Shot 2021-07-28 at 18.42.31.png

Neste caso, quando a variável text no primeiro container mudar, será necessário redesenhar o Widget Padding, a Column, os outros Containers e por fim os Texts, o que traria gastos desnecessários para a nossa aplicação.

Screen Shot 2021-07-28 at 18.42.40.png

Nesse segundo caso, os Widgets Text ficarão ouvindo através do gerenciador de estado, as mudanças na variável text. Assim, quando o Container no topo da árvore de elementos mudar o valor de text, os Widgets que estarão ouvindo essa mudança, notificando o Flutter para redesenhar esses Widgets. Logo, temos pouquíssimo gasto em relação a processamento.

Esse Gerenciador de Estado fica fora da árvore de elementos notificando todo mundo que estiver escutando quando algum mudança é realizada.

Soluções de Gerenciamento de Estado em Flutter

Hoje temos algumas soluções para gerenciamento de estado. Listarei aqui para maiores pesquisas:

  • GetX: Um pacote para gerenciamento de estado e mais um monte de ‘facilidades’ para quem está programando em Flutter.
  • BLoC: Um pacote que engloba o Business Logic Component, que nada mais é uma abstração do estado da aplicação. Ela é um pouco mais complicada e acaba criando muitos arquivos, porém vem sendo usada já há algum tempo e pode se dizer mais madura.
  • Provider: Um pacote que além de gerenciamento de estado, disponibiliza para toda a árvore de elementos um objeto ou valor, o que facilita na hora de passar valores para sua árvore de elementos.
  • Mobx: Um pacote que é baseado em implementações de Mobx de outras linguagens. Ficou bastante popular e usa geração de código para facilitar e diminuir a quantidade de código que você precisa escrever.

Além desses há aqueles que o Flutter já recomenda e que podem ser encontrados na documentação oficial.

Conclusão

Gerenciamento de Estado ainda é uma área do Flutter em crescimento, temos muitas opções e vale experimentar cada uma para avaliar qual você se sente mais à vontade. Eu particularmente sempre gostei do Provider por sua simplicidade, mas o GetX tem se mostrado igualmente simples e até mais poderoso, o que me faz querer aprender e estudar cada vez mais. Recomendo o mesmo para todos.

Kevin Santos
Software Engineer | Arquitetura de software, infraestrutura, desenvolvimento web e mobile. Procurando a solução certa pra cada problema. Programador até nas horas vagas.