Flutter Bloc
Published: 2024-06-04 12:35:02

BLoC (Business Logic Component) separates business logic from UI in a Flutter application, ensuring a clean and testable codebase. It utilizes streams to handle events and states, allowing for a reactive approach to state management. By adopting BLoC, you can create scalable and maintainable applications that are easier to debug and test.

##Key Components of BLoC

- Event: Represents user actions or events within the app.

- State: Represents the state of the UI based on events.

- Bloc: Manages events and emits corresponding states.

- BlocBuilder: Builds UI based on the current state.

- BlocListener: Listens for state changes to perform side effects.

- BlocProvider: Provides BLoC to the widget tree.


##Creating a BLoC

**Event: User Actions or Events**
Events in BLoC are simple classes that represent user actions or events within the app. They are the triggers that cause the BLoC to react and emit new states. Events are dispatched to the BLoC using the **add** method.
```
abstract class CounterEvent {}

class IncrementEvent extends CounterEvent {}

class DecrementEvent extends CounterEvent {}

```

In the above example, **IncrementEvent **and **DecrementEvent **are used to increase or decrease the counter.

**State: UI State Based on Events**
States are also simple classes that represent the UI's state. The BLoC emits new states in response to events. The UI rebuilds itself based on these states.

```
abstract class CounterState {}

class CounterInitial extends CounterState {
  final int counter;
  CounterInitial(this.counter);
}

```
Here, **CounterInitial** holds the counter value and is the state managed by the BLoC.

**Bloc: Manages Events and States**
The **Bloc** class is where the magic happens. It handles incoming events, processes them, and emits new states. The Bloc class extends the Bloc base class provided by the flutter_bloc package.

```
import 'package:flutter_bloc/flutter_bloc.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial(0)) {
    on<IncrementEvent>((event, emit) {
      emit(CounterInitial((state as CounterInitial).counter + 1));
    });
    on<DecrementEvent>((event, emit) {
      emit(CounterInitial((state as CounterInitial).counter - 1));
    });
  }
}

```
In this example, the BLoC reacts to **IncrementEvent** and **DecrementEvent** by emitting a new state with the updated counter value.

**BlocBuilder: Builds UI Based on State**
**BlocBuilder** is a Flutter widget that rebuilds its UI in response to new states emitted by the BLoC. It listens to the BLoC and triggers a rebuild whenever a new state is emitted.

```
BlocBuilder<CounterBloc, CounterState>(
  builder: (context, state) {
    if (state is CounterInitial) {
      return Center(
        child: Text('Counter: ${state.counter}'),
      );
    }
    return Container();
  },
)

```
BlocBuilder rebuilds the Text widget with the current counter value whenever the state changes.

**BlocListener: Listens for State Changes**
BlocListener is another Flutter widget that listens for state changes but does not rebuild the UI. Instead, it allows you to perform side effects such as showing a SnackBar.

```
BlocListener<CounterBloc, CounterState>(
  listener: (context, state) {
    if (state is CounterInitial) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Counter: ${state.counter}')),
      );
    }
  },
  child: BlocBuilder<CounterBloc, CounterState>(
    builder: (context, state) {
      if (state is CounterInitial) {
        return Center(
          child: Text('Counter: ${state.counter}'),
        );
      }
      return Container();
    },
  ),
)

```
BlocListener shows a SnackBar with the current counter value whenever the state changes.


**BlocProvider: Provides BLoC to the Widget Tree**
BlocProvider is a Flutter widget that provides an instance of the BLoC to the widget tree. It ensures that the BLoC can be accessed from any descendant widget.

```
void main() {
  runApp(
    BlocProvider(
      create: (context) => CounterBloc(),
      child: MyApp(),
    ),
  );
}
```
BlocProvider wraps the MyApp widget, providing CounterBloc to the entire widget tree.

##Conclusion
Understanding BLoC is essential for managing state in complex Flutter applications. With events, states, BlocBuilder, BlocListener, and BlocProvider, you can build scalable and maintainable apps. By following these examples, you can start using BLoC in your projects to improve code organization and maintainability.