hydrated_bloc 9.1.5 copy "hydrated_bloc: ^9.1.5" to clipboard
hydrated_bloc: ^9.1.5 copied to clipboard

An extension to the bloc state management library which automatically persists and restores bloc states.

Hydrated Bloc

build codecov Star on Github Flutter Website Awesome Flutter Flutter Samples License: MIT Discord Bloc Library

An extension to package:bloc which automatically persists and restores bloc and cubit states. Built to work with package:bloc.

Learn more at bloclibrary.dev!


Sponsors #

Our top sponsors are shown below! [Become a Sponsor]


Overview #

hydrated_bloc exports a Storage interface which means it can work with any storage provider. Out of the box, it comes with its own implementation: HydratedStorage.

HydratedStorage is built on top of hive for a platform-agnostic, performant storage layer. See the complete example for more details.

Usage #

Setup HydratedStorage #

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  HydratedBloc.storage = await HydratedStorage.build(
    storageDirectory: kIsWeb
        ? HydratedStorage.webStorageDirectory
        : await getApplicationDocumentsDirectory(),
  );
  runApp(App());
}

Create a HydratedCubit #

class CounterCubit extends HydratedCubit<int> {
  CounterCubit() : super(0);

  void increment() => emit(state + 1);

  @override
  int fromJson(Map<String, dynamic> json) => json['value'] as int;

  @override
  Map<String, int> toJson(int state) => { 'value': state };
}

Create a HydratedBloc #

sealed class CounterEvent {}
final class CounterIncrementPressed extends CounterEvent {}

class CounterBloc extends HydratedBloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>((event, emit) => emit(state + 1));
  }

  @override
  int fromJson(Map<String, dynamic> json) => json['value'] as int;

  @override
  Map<String, int> toJson(int state) => { 'value': state };
}

Now the CounterCubit and CounterBloc will automatically persist/restore their state. We can increment the counter value, hot restart, kill the app, etc... and the previous state will be retained.

HydratedMixin #

class CounterCubit extends Cubit<int> with HydratedMixin {
  CounterCubit() : super(0) {
    hydrate();
  }

  void increment() => emit(state + 1);

  @override
  int fromJson(Map<String, dynamic> json) => json['value'] as int;

  @override
  Map<String, int> toJson(int state) => { 'value': state };
}

Custom Storage Directory #

Any storageDirectory can be used when creating an instance of HydratedStorage:

final storage = await HydratedStorage.build(
  storageDirectory: await getApplicationDocumentsDirectory(),
);

Custom Hydrated Storage #

If the default HydratedStorage doesn't meet your needs, you can always implement a custom Storage by simply implementing the Storage interface and initializing HydratedBloc with the custom Storage.

// my_hydrated_storage.dart

class MyHydratedStorage implements Storage {
  @override
  dynamic read(String key) {
    // TODO: implement read
  }

  @override
  Future<void> write(String key, dynamic value) async {
    // TODO: implement write
  }

  @override
  Future<void> delete(String key) async {
    // TODO: implement delete
  }

  @override
  Future<void> clear() async {
    // TODO: implement clear
  }
}
// main.dart
HydratedBloc.storage = MyHydratedStorage();
runApp(MyApp());

Testing #

When writing unit tests for code that uses HydratedBloc, it is recommended to stub the Storage implementation using package:mocktail.

import 'package:flutter_test/flutter_test.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:mocktail/mocktail.dart';

class MockStorage extends Mock implements Storage {}

void main() {
  late Storage storage;

  setUp(() {
    storage = MockStorage();
    when(
      () => storage.write(any(), any<dynamic>()),
    ).thenAnswer((_) async {});
    HydratedBloc.storage = storage;
  });

  // ...
}

You can also stub the storage.read API in individual tests to return cached state:

testWidgets('...', (tester) async {
  when<dynamic>(() => storage.read('$MyBloc')).thenReturn(MyState().toJson());

  // ...
});

Dart Versions #

  • Dart 2: >= 2.12

Maintainers #

852
likes
160
points
117k
downloads
screenshot

Publisher

verified publisherbloclibrary.dev

Weekly Downloads

An extension to the bloc state management library which automatically persists and restores bloc states.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#bloc #cache #state-management

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

bloc, hive, meta, synchronized

More

Packages that depend on hydrated_bloc