reactive_notifier_hydrated library

Hydrated extension for ReactiveNotifier - Automatic state persistence.

This package provides hydrated versions of ReactiveNotifier components that automatically persist and restore state using a storage backend.

Quick Start

  1. Initialize storage in your main function:
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  HydratedNotifier.storage = await SharedPreferencesStorage.getInstance();
  runApp(MyApp());
}
  1. Use hydrated components:
// Simple state with HydratedReactiveNotifier
mixin CounterService {
  static final counter = HydratedReactiveNotifier<CounterState>(
    create: () => CounterState(count: 0),
    storageKey: 'counter',
    toJson: (state) => state.toJson(),
    fromJson: (json) => CounterState.fromJson(json),
  );
}

// Complex state with HydratedViewModel
class SettingsViewModel extends HydratedViewModel<SettingsState> {
  SettingsViewModel() : super(
    initialState: SettingsState.defaults(),
    storageKey: 'settings',
    toJson: (state) => state.toJson(),
    fromJson: (json) => SettingsState.fromJson(json),
  );

  void toggleDarkMode() {
    transformState((s) => s.copyWith(isDarkMode: !s.isDarkMode));
  }
}

// Async data with HydratedAsyncViewModelImpl
class UserViewModel extends HydratedAsyncViewModelImpl<UserModel> {
  UserViewModel() : super(
    AsyncState.initial(),
    storageKey: 'user',
    toJson: (user) => user.toJson(),
    fromJson: (json) => UserModel.fromJson(json),
  );

  @override
  Future<UserModel> init() async {
    return await userRepository.fetchUser();
  }
}

Custom Storage

Implement HydratedStorage for custom backends:

class HiveStorage implements HydratedStorage {
  final Box _box;
  HiveStorage(this._box);

  @override
  Future<Map<String, dynamic>?> read(String key) async {
    return _box.get(key);
  }

  @override
  Future<void> write(String key, Map<String, dynamic> value) async {
    await _box.put(key, value);
  }

  @override
  Future<void> delete(String key) async {
    await _box.delete(key);
  }

  @override
  Future<void> clear() async {
    await _box.clear();
  }
}

Classes

AsyncState<T>
AsyncViewModelImpl<T>
Base ViewModel implementation for handling asynchronous operations with state management.
HydratedAsyncViewModelImpl<T>
An AsyncViewModelImpl that automatically persists and restores its data.
HydratedConfig<T>
Configuration for hydrated state persistence.
HydratedNotifier
Global storage instance used by all hydrated notifiers.
HydratedReactiveNotifier<T>
A wrapper around ReactiveNotifier that provides automatic state persistence.
HydratedStorage
Abstract interface for hydrated state storage.
HydratedViewModel<T>
A ViewModel that automatically persists and restores its state.
ReactiveAsyncBuilder<VM, T>
ReactiveBuilder<T>
Reactive Builder for simple state or direct model state.
ReactiveContextBuilder
ReactiveContextBuilder for explicit InheritedWidget strategy
ReactiveContextPreservationWrapper
Enhanced widget preservation with intelligent caching
ReactiveFutureBuilder<T>
A widget that handles a Future and provides reactive notification through a ReactiveNotifier to avoid flickering when navigating between screens.
ReactiveNotifier<T>
A reactive state management solution that supports:
ReactiveNotifierViewModel<VM extends ViewModel<T>, T>
This class is used similarly to ReactiveNotifier, but it requires calling the ViewModel and the type of data it returns. It provides a wrapper around the ViewModel to manage state and updates via a ReactiveNotifier.
ReactiveStreamBuilder<VM, T>
ReactiveViewModelBuilder<VM, T>
ReactiveViewModelBuilder ReactiveViewModelBuilder is a specialized widget for handling ViewModel states It's designed to work specifically with StateNotifierImpl implementations and provides efficient state management and rebuilding mechanisms
SharedPreferencesStorage
Default HydratedStorage implementation using SharedPreferences.
ViewModel<T>
Used in ViewModel classes where all business logic should reside.

Enums

AsyncStatus
State of asynd ata, example, success, error, etc this async state shouldbe inside of asynNotifier for value of type AsyncState.

Mixins

HydratedMixin<T>
A mixin that provides state persistence functionality.
ViewModelContextService
Mixin that provides organic context access to ViewModels Add this to ViewModel<T> and AsyncViewModelImpl<T> base classes No setup required - context is automatically available when builders are active

Extensions

ReactiveContextBase on BuildContext
Base extension for creating specific extensions
ReactiveContextGeneric on BuildContext
Optional generic extension
ReactiveContextPreservation on BuildContext
Extension methods for BuildContext preservation
ReactiveContextWidgetPreservation on Widget
Extension methods for widget preservation

Functions

cleanupPreservedWidgets() → void
Clean up all preserved widgets
getPreservationStatistics() Map<String, dynamic>
Get debug statistics for widget preservation
preserveWidget(Widget widget, [String? key]) Widget
Public API functions for widget preservation
preserveWidgets(List<Widget> widgets, [String? baseKey]) List<Widget>
Preserve multiple widgets with batch operation