DEV Community

Cover image for bloc
Rana Ayman
Rana Ayman

Posted on • Updated on

bloc

Efficient State Management in Flutter with Cubit and Freezed:

In the realm of Flutter development, managing state efficiently and effectively is crucial for building responsive and maintainable applications. One powerful combination for state management is using Cubit from the BLoC (Business Logic Component) package alongside the Freezed package. This approach not only provides a clear separation of concerns but also enhances code readability and maintainability.

Setting Up Cubit and Freezed
Let's walk through an example where we implement a login feature using Cubit and Freezed. The directory structure is organized to ensure each screen has its own logic folder containing the necessary Cubit files. For the login feature, we'll create a login_cubit.dart and login_state.dart.

Directory Structure

lib/
│
├── features/
│   ├── login/
│   │   ├── logic/
│   │   │   ├── cubit/
│   │   │   │   ├── login_cubit.dart
│   │   │   │   └── login_state.dart
Enter fullscreen mode Exit fullscreen mode

Defining the State with Freezed
In login_state.dart, we define the different states for the login process using the Freezed package. Freezed simplifies the creation of union types (a.k.a. sealed classes), making our state definitions clean and expressive.

First, add the necessary dependencies in pubspec.yaml:

dependencies:
  flutter_bloc: ^8.1.3
  freezed: ^1.0.0
  freezed_annotation: ^1.0.0
  flutter:
    sdk: flutter
Enter fullscreen mode Exit fullscreen mode

Then, create the login_state.dart file:

Image description

In this file:

initial represents the initial state when the Cubit is created.
loading is used to indicate that the login process is ongoing.
success holds the data returned upon a successful login.
error carries an error message if the login process fails.
to generate the necessary code for the Freezed package, we use the part directive and run a code generation command. The part 'login_state.freezed.dart'; line tells the Dart compiler to include the generated file.

Generating the Code
To generate the code, run the following command in your terminal:

dart run build_runner build --delete-conflicting-outputs 

Enter fullscreen mode Exit fullscreen mode

Implementing the Cubit

Next, we'll implement the login_cubit.dart to manage the state transitions.

Image description

In the LoginCubit:

We initiate the Cubit with the initial state.
The login method simulates a network call, emitting a loading state during the process.
If the login is successful, we emit a success state with some dummy data.
In case of failure, we emit an error state with an appropriate error message.

Utilizing the Cubit in UI

Finally, we integrate the Cubit into our UI to handle state changes and display corresponding views.

Image description

LoginBlocListener widget that listens to state changes in a LoginCubit and reacts to different states by displaying dialogs for loading, success, and error conditions.

In the LoginScreen:

LoginScreen integrates the LoginBlocListener to handle state changes during the login process.
The LoginBlocListener in the login screen is responsible for monitoring the state changes of the LoginCubit and performing appropriate actions based on the current state. It helps manage the user interface's response to different login states (e.g., loading, success, error) without cluttering the main LoginScreen widget code.

Top comments (0)