Hydrated BLoC in Flutter: How to Use Hydrated Bloc

image

Introduction

State management is an essential aspect of Flutter app development, especially when working on complex applications. One of the most powerful tools for managing states is the BLoC (Business Logic Component) pattern. But what if you need your state to persist even after the app is closed and reopened? That’s where Hydrated BLoC comes into play.

In this article, we’ll discuss what Hydrated BLoC is, its advantages and disadvantages, why we use it, and provide a detailed implementation example to help you integrate it into your own Flutter applications.

What is Hydrated BLoC?

Hydrated BLoC is an extension of the BLoC (Business Logic Component) pattern that automatically persists and restores the state of a BLoC. When an app is closed or killed and later reopened, the BLoC’s state can be restored without losing any data.

Hydrated BLoC builds on top of the core BLoC library and adds persistence, which means your app’s state is saved to storage (like disk storage) and automatically rehydrated (restored) when the app starts again.

Hydrated BLoC uses hydrated_storage to handle the persistence of state across app sessions. It’s built with simplicity and performance in mind, ensuring your BLoC’s state remains in sync, even in cases of unexpected app terminations.

Advantages of Hydrated BLoC

1. Automatic State Persistence

One of the main advantages of Hydrated BLoC is that it automatically handles state persistence. You don’t need to manually save and restore the state when an app closes or restarts. This feature is very handy in apps where maintaining the user’s progress or input is essential, like forms, quizzes, or ongoing tasks.

2. Easy to Integrate

Hydrated BLoC is extremely easy to integrate into an existing BLoC architecture. You only need to make a few adjustments, and your BLoC will be able to persist in its state.

3. Flexible and Customizable

The Hydrated BLoC package allows for custom serialization. This means you can serialize your complex objects or custom types, making it very flexible to handle more complex app states.

4. Offline Persistence

Since Hydrated BLoC uses local storage, it allows offline persistence of data. The user can close the app, come back later, and still find everything in the same state, even without an internet connection.

Disadvantages of Hydrated BLoC

1. Increased Storage Usage

Since Hydrated BLoC saves data to local storage, it can increase storage usage on the user’s device. If not managed properly, this can cause storage issues, especially if you’re storing large or complex states.

2. Overhead in State Management

In cases where state persistence isn’t essential, Hydrated BLoC can add unnecessary overhead to state management. If you don’t need to save the state across sessions, using Hydrated BLoC can introduce complexity without significant benefits.

3. Security Concerns

If you’re storing sensitive data in the BLoC’s state, you’ll need to take additional precautions, such as encrypting the data. Hydrated BLoC doesn’t provide encryption by default, so it’s up to the developer to ensure sensitive information is stored securely.

Why We Use Hydrated BLoC

Hydrated BLoC is ideal for applications where the user’s progress or actions need to persist even after they close the app.

Here are some reasons why developers choose Hydrated BLoC:
  • User Experience: It improves the user experience by maintaining the app’s state between sessions. Users can pick up where they left off without any disruptions.
  • Forms and Input: In forms, questionnaires, or multi-step wizards, Hydrated BLoC ensures the user doesn’t lose progress when they close the app.
  • Offline Support: For apps that need to function offline, Hydrated BLoC can help keep states consistent even when the user doesn’t have internet access.
  • E-Commerce or To-Do List Apps: Users can add items to the cart, close the app, and when they return, the cart remains intact.

Example: Implementing Hydrated BLoC in Flutter

Let’s look at a step-by-step implementation of Hydrated BLoC using a simple counter app.

Step 1: Add Dependencies

First, add the required dependencies to your pubspec.yaml file.

dependencies:
  flutter:
    sdk: flutter
  flutter_bloc: ^8.0.1
  hydrated_bloc: ^8.0.0
  hydrated_storage: ^6.1.0

Then, run flutter pub get to install the packages.

Step 2: Create the Counter BLoC

Now, let’s create a simple Counter BLoC that extends HydratedBloc. This BLoC will increment and decrement a counter and persist the state across sessions.

import 'package:hydrated_bloc/hydrated_bloc.dart';

class CounterCubit extends HydratedBloc<int, int> {
  CounterCubit() : super(0); // Initial state is 0

  // Increment the counter
  void increment() => emit(state + 1);

  // Decrement the counter
  void decrement() => emit(state - 1);

  // Override to save the current state to storage
  @override
  int? fromJson(Map<String, dynamic> json) {
    return json['value'] as int?;
  }

  // Override to load the state from storage
  @override
  Map<String, dynamic>? toJson(int state) {
    return {'value': state};
  }
}

Here, fromJson and toJson methods handle serializing and deserializing the state, respectively. The state is stored as a simple integer in this example.

Step 3: Set Up Hydrated Storage

To use Hydrated BLoC, we need to initialize the HydratedStorage. This is typically done in the main.dart file.

import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';
import 'counter_cubit.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final storage = await HydratedStorage.build(
    storageDirectory: await getApplicationDocumentsDirectory(),
  );

  HydratedBloc.storage = storage;

  runApp(MyApp());
}

This code initializes the HydratedStorage by pointing to the app’s documents directory, ensuring that the BLoC state will be stored on disk.

Step 4: Create the UI

Next, create the UI for the Counter app that uses the CounterCubit.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_cubit.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hydrated BLoC Counter',
      home: BlocProvider(
        create: (_) => CounterCubit(),
        child: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Hydrated BLoC Counter'),
      ),
      body: Center(
        child: BlocBuilder<CounterCubit, int>(
          builder: (context, count) {
            return Text('$count', style: TextStyle(fontSize: 48));
          },
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            onPressed: () => context.read<CounterCubit>().increment(),
            child: Icon(Icons.add),
          ),
          SizedBox(height: 10),
          FloatingActionButton(
            onPressed: () => context.read<CounterCubit>().decrement(),
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

In this UI, the BlocBuilder listens for state changes and rebuilds the widget when the state is updated. The FloatingActionButton increments and decrements the counter, and thanks to Hydrated BLoC, the state is saved and restored automatically.

Step 5: Test the Application

Run the app, increment or decrement the counter, then close and restart the app. You’ll notice that the counter value persists between sessions!

Conclusion

Hydrated BLoC is a powerful extension of the BLoC pattern that provides automatic state persistence, making it ideal for apps where maintaining the user’s progress across sessions is essential. While it adds a bit of complexity and storage overhead, the benefits of maintaining state across app restarts make it a great fit for many types of applications, particularly those requiring offline functionality or saving user data.

With the example provided, you can easily implement Hydrated BLoC in your own Flutter projects and enjoy the advantages of automatic state persistence.

Leave a Comment

Your email address will not be published. Required fields are marked *