State Managementintermediate

Riverpod AsyncNotifier

Modern Riverpod 2.x AsyncNotifier pattern for async state management with codegen-ready syntax.

#riverpod#state-management#async
dart
1import 'package:riverpod_annotation/riverpod_annotation.dart';
2 
3part 'user_provider.g.dart';
4 
5@riverpod
6class UserNotifier extends _$UserNotifier {
7 @override
8 Future<User> build(String userId) async {
9 return _fetchUser(userId);
10 }
11 
12 Future<void> refresh() async {
13 state = const AsyncLoading();
14 state = await AsyncValue.guard(() => _fetchUser(ref.read(userIdProvider)));
15 }
16 
17 Future<void> updateName(String newName) async {
18 final current = state.valueOrNull;
19 if (current == null) return;
20 
21 state = const AsyncLoading();
22 state = await AsyncValue.guard(() async {
23 final updated = await ref.read(userRepositoryProvider).updateName(current.id, newName);
24 return updated;
25 });
26 }
27 
28 Future<User> _fetchUser(String id) {
29 return ref.read(userRepositoryProvider).getUser(id);
30 }
31}
32 
33// Simple provider
34@riverpod
35Future<List<Post>> userPosts(Ref ref, String userId) async {
36 final user = await ref.watch(userNotifierProvider(userId).future);
37 return ref.read(postRepositoryProvider).getPostsByUser(user.id);
38}
39 
40// Usage
41class UserPage extends ConsumerWidget {
42 const UserPage({super.key, required this.userId});
43 final String userId;
44 
45 @override
46 Widget build(BuildContext context, WidgetRef ref) {
47 final userAsync = ref.watch(userNotifierProvider(userId));
48 return userAsync.when(
49 data: (user) => Text(user.name),
50 loading: () => const CircularProgressIndicator(),
51 error: (err, _) => Text('Error: $err'),
52 );
53 }
54}