Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Build cross-platform Flutter 3 apps with Riverpod/Bloc state management, GoRouter navigation, and performance optimization.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/riverpod-state.md
1# Riverpod State Management23## Provider Types45```dart6import 'package:flutter_riverpod/flutter_riverpod.dart';78// Simple state9final counterProvider = StateProvider<int>((ref) => 0);1011// Async state (API calls)12final usersProvider = FutureProvider<List<User>>((ref) async {13final api = ref.read(apiProvider);14return api.getUsers();15});1617// Stream state (real-time)18final messagesProvider = StreamProvider<List<Message>>((ref) {19return ref.read(chatServiceProvider).messagesStream;20});21```2223## Notifier Pattern (Riverpod 2.0)2425```dart26@riverpod27class TodoList extends _$TodoList {28@override29List<Todo> build() => [];3031void add(Todo todo) {32state = [...state, todo];33}3435void toggle(String id) {36state = [37for (final todo in state)38if (todo.id == id) todo.copyWith(completed: !todo.completed) else todo,39];40}4142void remove(String id) {43state = state.where((t) => t.id != id).toList();44}45}4647// Async Notifier48@riverpod49class UserProfile extends _$UserProfile {50@override51Future<User> build() async {52return ref.read(apiProvider).getCurrentUser();53}5455Future<void> updateName(String name) async {56state = const AsyncValue.loading();57state = await AsyncValue.guard(() async {58final updated = await ref.read(apiProvider).updateUser(name: name);59return updated;60});61}62}63```6465## Usage in Widgets6667```dart68// ConsumerWidget (recommended)69class TodoScreen extends ConsumerWidget {70const TodoScreen({super.key});7172@override73Widget build(BuildContext context, WidgetRef ref) {74final todos = ref.watch(todoListProvider);7576return ListView.builder(77itemCount: todos.length,78itemBuilder: (context, index) {79final todo = todos[index];80return ListTile(81title: Text(todo.title),82leading: Checkbox(83value: todo.completed,84onChanged: (_) => ref.read(todoListProvider.notifier).toggle(todo.id),85),86);87},88);89}90}9192// Selective rebuilds with select93class UserAvatar extends ConsumerWidget {94const UserAvatar({super.key});9596@override97Widget build(BuildContext context, WidgetRef ref) {98final avatarUrl = ref.watch(userProvider.select((u) => u?.avatarUrl));99100return CircleAvatar(101backgroundImage: avatarUrl != null ? NetworkImage(avatarUrl) : null,102);103}104}105106// Async state handling107class UserProfileScreen extends ConsumerWidget {108@override109Widget build(BuildContext context, WidgetRef ref) {110final userAsync = ref.watch(userProfileProvider);111112return userAsync.when(113data: (user) => Text(user.name),114loading: () => const CircularProgressIndicator(),115error: (err, stack) => Text('Error: $err'),116);117}118}119```120121## Quick Reference122123| Provider | Use Case |124|----------|----------|125| `Provider` | Computed/derived values |126| `StateProvider` | Simple mutable state |127| `FutureProvider` | Async operations (one-time) |128| `StreamProvider` | Real-time data streams |129| `NotifierProvider` | Complex state with methods |130| `AsyncNotifierProvider` | Async state with methods |131