Question #213MediumDart Basics

Describe about riverpod statemangement ? with some live examples and riverpod annotation use cases too ? also define the lifecycle of the riverpod ? also when we use riverpod annotation will the lifecycle is managed by automatically ?

#state#riverpod

Answer

Overview

Riverpod is a reactive state management + dependency injection library for Flutter. It is the evolution of Provider -- context-free, compile-safe, and with built-in async support.


Core Providers

dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

// 1. Provider -- simple read-only value
final greetingProvider = Provider<String>((ref) => 'Hello, Alice!');

// 2. StateProvider -- simple mutable state
final counterProvider = StateProvider<int>((ref) => 0);

// 3. FutureProvider -- async data
final userProvider = FutureProvider<User>((ref) async {
  return await fetchUser();
});

// 4. StreamProvider -- stream data
final notificationsProvider = StreamProvider<List<Notification>>((ref) {
  return NotificationService.stream;
});

// 5. StateNotifierProvider -- complex state
final cartProvider = StateNotifierProvider<CartNotifier, CartState>(
  (ref) => CartNotifier(),
);

class CartNotifier extends StateNotifier<CartState> {
  CartNotifier() : super(CartState.initial());

  void addItem(Product p) => state = state.copyWith(
    items: [...state.items, p],
    total: state.total + p.price,
  );
}

Riverpod in Widgets

dart
void main() => runApp(ProviderScope(child: MyApp())); // Required wrapper

class HomeScreen extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider); // Reactive
    final user = ref.watch(userProvider);     // FutureProvider

    return Scaffold(
      body: Column(children: [
        Text('Count: $count'),
        user.when(
          data: (u) => Text('Hello, ${u.name}'),
          loading: () => CircularProgressIndicator(),
          error: (e, _) => Text('Error: $e'),
        ),
      ]),
      floatingActionButton: FloatingActionButton(
        onPressed: () => ref.read(counterProvider.notifier).state++,
      ),
    );
  }
}

Riverpod Lifecycle

text
ProviderScope created (app start)
    |
Provider first watched (ref.watch)
    | Provider created (build method called)
State maintained while listened to
    |
No listeners remain
    | (if autoDispose) Provider disposed
Provider rebuild when dependency changes
    | (Watchers rebuild automatically)

autoDispose -- Automatic Lifecycle Management

dart
// Without autoDispose -- lives until app closes
final counterProvider = StateProvider<int>((ref) => 0);

// With autoDispose -- disposed when no widget is listening
final searchProvider = StateProvider.autoDispose<String>((ref) => '');

// Cancel async work on dispose
final dataProvider = FutureProvider.autoDispose<Data>((ref) async {
  final cancelToken = CancelToken();
  ref.onDispose(() => cancelToken.cancel()); // Cleanup on dispose
  return await api.fetchData(cancelToken: cancelToken);
});

Riverpod Annotations (Code Generation)

dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'providers.g.dart'; // Generated

// @riverpod generates provider automatically

int counter(CounterRef ref) => 0;


Future<User> fetchUser(FetchUserRef ref, {required int id}) async {
  return await ref.watch(apiServiceProvider).getUser(id);
}

// With keepAlive (true = permanent, false = autoDispose -- default)
(keepAlive: false)
Future<List<Product>> products(ProductsRef ref) async {
  return ref.watch(productRepoProvider).getProducts();
}
// When using annotations, lifecycle is managed AUTOMATICALLY:
// autoDispose is the DEFAULT (keepAlive: false)
// Provider is disposed when no widgets listen
// Recreated when first watched again

ref methods

MethodDescription
text
ref.watch(provider)
Subscribe + rebuild on change
text
ref.read(provider)
Read once, no subscription
text
ref.listen(provider, callback)
Side effects on change
text
ref.invalidate(provider)
Force re-fetch
text
ref.onDispose(fn)
Cleanup when provider disposed

Lifecycle Summary: Provider created on first

text
watch
, alive while watched, disposed when no listeners (if
text
autoDispose
). With
text
@riverpod
annotation,
text
autoDispose
is default -- lifecycle is fully automatic.