Bloc State Management para iniciantes — Flutter

Tempo de leitura: 6 minutes

Ei, pessoal, vocês estão enfrentando um problema para entender flutter bloc state management para que tenham uma ideia clara para entender hoje?

Coisas necessárias para iniciar o Bloc:

1: Você deve ter uma compreensão da linguagem dart.

2: Você deve ter um conhecimento básico do flutter framework.

Então vamos aprender!

 

Quando alguém diz BLoC sua reação provavelmente é assim 😵. Todo mundo ensinou que é tão complexo gerenciar estados, mas não é. Começaremos com etapas muito básicas para que você possa entendê-las facilmente.

O que é BLoC?

‘BLoC’ é denominado um Componente de Lógica de Negócios. Um padrão de projeto apresentado por Paolo Soares e Cong hui, do Google. O BLoC nos ajuda a separar a lógica de negócios da interface do usuário.

Então, o que é Lógica de Negócios? 🤔

Vamos dar um exemplo. Suponha que você queira implementar a funcionalidade de login por meio do firebase. Quais serão seus primeiros passos? você primeiro projetará uma interface de interface do usuário com um campo de texto e um botão de login. Depois disso, você criará um projeto firebase e registrará seu projeto para começar a usar o Firebase, certo?

Provavelmente sua reação agora 😀

Então, onde está a lógica de negócios? Vem quando você escreve a função de login quando o usuário toca no botão de login. Veja este código simples para o login do firebase.

static Future<User?> signInUsingEmailPassword({
  required String email,
  required String password,
  required BuildContext context,
}) async {
  FirebaseAuth auth = FirebaseAuth.instance;
  User? user;

  try {
    UserCredential userCredential = await auth.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
    user = userCredential.user;
  } on FirebaseAuthException catch (e) {
    if (e.code == 'user-not-found') {
      print('No user found for that email.');
    } else if (e.code == 'wrong-password') {
      print('Wrong password provided.');
    }
  }

  return user;
}

Isso é o que diz a lógica de negócios. Iniciaremos o bloco com um aplicativo de contador simples gerenciando estados e eventos.

 

Como funciona o BloC?

Se falarmos sobre um padrão de bloco de vibração simples para funcionar em State -> Event -> Bloc. Vamos mergulhar fundo nisso. O estado é como conter todos os seus dados que serão exibidos em sua interface do usuário. O State é a ação que será realizada para fazer algo. O Bloc possui todos os manipuladores de eventos que irão agir como chamada de evento a partir de uma interface de usuário. Parece muito complexo? não se preocupe, deixe-me compartilhar um fluxo de Bloc primeiro.

Referindo-se a este diagrama de fluxo, vamos falar tecnicamente sobre o que está acontecendo aqui. A interface do usuário será seu arquivo dart que contém apenas a interface que não contém nenhuma lógica de negócios que acontecerá ao clicar no botão de login. Digamos que você tenha dois campos de texto, um é e-mail e o outro é senha e um botão de login simples.

 

Agora, quando você clicar no botão de login da interface do usuário, ele atingirá o evento e, como você pode ver, a seta da UI para o bloc. Agora, como é uma função assíncrona, ela fará solicitações HTTP para o back-end como o firebase. O servidor dá uma resposta, você pode ver uma seta dos dados para o bloc. Agora esses dados serão armazenados no state do bloc e teremos o Bloc Builder em nossa UI de interface que ouvirá as alterações e atualizará nossa UI.

Provavelmente sua reação agora 😀

 

Não se preocupe agora, vou explicar isso em detalhes. Vamos começar a codificar com o VsCode da Microsoft.

Passos a seguir:

1: Crie um novo projeto flutter e você pode nomeá-lo BlocExemplo.
–> Vc pode criar com outra forma / outro IDE. (Uso o Vscode e Linha de comando do Windows).

Criação no terminal do Windows

  • Linha de criação de projetos –> flutter create --project-name=blocexemplo --org br.com.capsistema --platforms android ./BlocExemplo
  • Abrir o projeto criado (BlocExemplo)
  • Abrir no IDE (VsCode) user code .

  • Após o projeto abrir, vc verá este menu lateral, na pasta superior em roxo, com o projeto na parte em amarelo.
  • Apenas para Android neste demo (seta azul)
  • No retângulo em cinza, você ver todos os packages que ira adicionar.
  • E a seta em vermelho é onde você ira efetuar a programação, em Flutter/Dart.

 

2: Adicione usando a linha no VsCode os packages necessários.

  • Indo na Paleta de Comando -> Dart: Add Dependency digitando os packages necessários como bloc, flutter_bloc.

  • No pubspec.yaml ficara assim como está abaixo.

  • Na seta em Amarelo informa a versão do Dart usada no momento no, caso 3.0.0
  • E usando o Flutter 3.10.0
  • Em vermelho são os packages usados o ‘cupertino_icons’ é padrão do flutter, ele já adiciona ele e os da dev_dependencies (usados para compilação ou teste)

 

3: Adicione as pastas e código a seguir como descrito e na foto.

  • Na pasta Lib crie as pastas (bloc e views)
  • Dentro da pasta bloc crie os seguintes arquivos (counter_bloc.dart, counter_event.dart, counter_state.dart)
  • Dentro da pasta view crie o seguinte arquivo (couter_view.dart)

 

Agora crie os códigos como descrito abaixo.

Arquivo -> Counter State

part of 'counter_bloc.dart';

class CounterState {
  final int counterValue;

  CounterState({required this.counterValue});

  factory CounterState.initial() => CounterState(counterValue: 0);

  CounterState copyWith({int? counterValue}) {
    return CounterState(
      counterValue: counterValue ?? this.counterValue,
    );
  }
}

Então eu simplesmente criei uma variável para o valor do contador que irá aumentar ou diminuir quando eu clicar no botão. Depois disso, um factory constructor para apenas inicializar meu valor de contador para zero. Depois disso, você pode ver a cópia com a função que é apenas uma cópia do nosso estado. O propósito de copiar é simplesmente atualizar o valor do estado fornecido. Se um valor não for fornecido, resta manter o valor anterior.

 

Arquivo -> Counter Event

part of 'counter_bloc.dart';

abstract class CounterEvent {}

class IncrementCounter extends CounterEvent {}

class DecrementCounter extends CounterEvent {}

O arquivo de evento conterá todos os eventos que serão acionados a partir da interface do usuário. Se quisermos incrementar o contador, o evento IncrementCounter será acionado para atualizar o valor do contador no arquivo de estado. O mesmo vale para decrementar o contador.

 

Arquivo -> Counter Bloc

import 'package:flutter_bloc/flutter_bloc.dart';

part 'counter_event.dart';

part 'counter_state.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterState.initial()) {}
}

Este é o arquivo de bloco onde o primeiro estado do contador é inicializado, significa que nosso construtor de fábrica inicializará o valor do estado. Consulte o código do arquivo de estado para torná-lo vizio.

on<IncrementCounter>((event, emit) => incrementCounter(event, emit));
on<DecrementCounter>((event, emit) => decrementCounter(event, emit));

Agora, se você ver essas duas linhas, ele virá em um arquivo de bloco. Sempre que um evento for chamado da interface do usuário, como incremento ou decremento, eles serão acionados. você pode ver ao retornar (=>) que a função irá chamar para lidar com este evento.

incrementCounter(IncrementCounter event, Emitter<CounterState> emit) {
  emit(state.copyWith(counterValue: state.counterValue + 1));
}

decrementCounter(DecrementCounter event, Emitter<CounterState> emit) {
  emit(state.copyWith(counterValue: state.counterValue - 1));
}

Se for um evento de incremento, a função de contador de incremento será executada. O emit é a função que atualiza o valor no estado e o valor do contador será atualizado. O que estou fazendo simplesmente pega o valor anterior do estado como state.counterValue e o incrementa em 1. Essa alteração será ouvida na interface do usuário, que será a 2ª parte deste artigo 😃

Código Completo do do Bloc.

import 'package:flutter_bloc/flutter_bloc.dart';

part 'counter_event.dart';

part 'counter_state.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterState.initial()) {
    on<IncrementCounter>((event, emit) => incrementCounter(event, emit));
    on<DecrementCounter>((event, emit) => decrementCounter(event, emit));
  }

  incrementCounter(IncrementCounter event, Emitter<CounterState> emit) {
    emit(state.copyWith(counterValue: state.counterValue + 1));
  }

  decrementCounter(DecrementCounter event, Emitter<CounterState> emit) {
    emit(state.copyWith(counterValue: state.counterValue - 1));
  }
}

Link do package usado em flutter

Esta é toda a sua lógica de negócios para o aplicativo contador para incrementar e diminuir o contador.

Inicialmente, pode ser um pouco difícil de entender, mas quando você codificar sozinho, começará a ficar cada vez mais fácil.