Gerenciamento de estados no Flutter
Tags: flutter, tutorial, dart, statemanagement
Published: 2023-05-07 16:29:25

Realizamos um monte de cursos para aprender sobre o framework queridinho para a programação em mobile (Claro... estamos falando de Flutter) e desde o início dessas aulas que assistimos não paramos de escutar no seguinte tópico: Gerenciamento de estados. Ao longo desse post vou tentar te explicar para o que serve esse famoso e como ele irá nos ajudar no consumo de informações dentro de nosso aplicativo.

Imagine o cenário em que você está criando uma aplicação voltado para um e-commerce utilizando uma arquitetura _MVVM_ onde temos dentro de uma View-Model os dados do carrinho de compras desse app. Pensa comigo... Enquanto você está saciando o seu desejo consumista vendo todos os produtos desse e-commerce e adicionando vários deles no seu carrinho você precisará desses mesmos produtos na sua tela de confirmação de pagamento para você pagar por cada um daqueles ítens que você adicionou previamente. E é justamente com gerenciamento de estados que temos esse compartilhamento de informações dentro do Flutter.

No mercado existem várias opções de abordagens voltadas para o gerenciamento de estados, podemos citar como exemplo: Provider, GetX, MobX, BloC



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sc1r65bbsrdapn3a1fcy.png)

Nesse gráfico conseguimos ver a quantidade de citações para as bibliotecas de gerenciamento de estados que são feitas para as vagas de desenvolvedor Flutter aí no mercado, já serve para termos um norteador do que estudarmos

Iremos utilizar no exemplo o Provider para exemplificarmos o gerenciamento de estados no Flutter. Antes de vermos a instância do nosso objeto sendo renderizados em várias telas do nosso aplicativo precisamos entender o conceito do padrão Singleton.
Este padrão irá garantir uma melhor performance em nossa aplicação visto que como o próprio nome do padrão diz teremos uma instância _"solteira"_ do nosso objeto a qual é acessível dentro de todo o contexto do aplicativo. Essa instância estará salva em memória.
Para o contexto da nossa aplicação de e-commerce vamos ter o CartViewModel que será criado dentro do MultiProvider (escolhi utilizar o MultiProvider para relembrar a cada um de vocês que é possível criar mais de um em nosso aplicativo)

```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<CartViewModel>.value(
          value: CartViewModel(),
        ),
      ],
      child: Main(),
    );
  }
}
```
Para reutilizarmos esse valor que está no CartViewModel podemos chamar o Provider.of para consumir os ítens contidos nele vou exemplificar utilizando o CartViewModel na CheckoutPage que seria a página a qual estaríamos finalizando o pagamento dos ítens contidos no CartViewModel.

```dart
class CheckoutPage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        cartViewModel = Provider.of<CartViewModel>(context);
        items = cartViewModel.items;
    }
}
```

Certo Lucas... Você explicou como prover essas informações com o MultiProvider, explicou como consumir essas informações através do Provider.of mas como que eu atualizo e consumo essas informações atualizadas. Tcharam!! É aí que utilizaremos o método notifyListeners(). Vamos ver o trecho de código a seguir.

```dart
  /// Método responsável por adicionar um ítem
  /// na lista do carrinho e notificar nas páginas
  /// que consomem essa informação via Provider.
  addItem(item Item) {
    this.items.add(item);
    notifyListeners();
  }
```

Esse método adiciona um objeto do tipo Item a lista de Item e ao final dispara o notifyListeners() que irá justamente atualizar o valor de Items onde ele é usado, no nosso exemplo temos a CheckoutPage mas no cenário de uma aplicação de maior porte poderia ser consumido em diversos locais.