1. Riverpod Setup
dependencies:
flutter_riverpod: ^2.5.0
riverpod_annotation: ^2.3.0
dev_dependencies:
riverpod_generator: ^2.4.0
build_runner: ^2.4.0
void main() {
runApp(const ProviderScope(child: MyApp()));
}
2. Provider Types
// Simple provider
final greetingProvider = Provider<String>((ref) => 'Hello Riverpod!');
// StateProvider — simple state
final counterProvider = StateProvider<int>((ref) => 0);
// FutureProvider — async data
final productsProvider = FutureProvider<List<Product>>((ref) async {
final repository = ref.watch(productRepositoryProvider);
return repository.getAll();
});
// StreamProvider
final messagesProvider = StreamProvider<List<Message>>((ref) {
return ref.watch(chatServiceProvider).messagesStream;
});
// StateNotifierProvider — complex state
class CartNotifier extends StateNotifier<List<CartItem>> {
CartNotifier() : super([]);
void add(Product product) {
state = [...state, CartItem(product: product, quantity: 1)];
}
void remove(String productId) {
state = state.where((item) => item.product.id != productId).toList();
}
double get total => state.fold(0, (sum, item) => sum + item.product.price * item.quantity);
}
final cartProvider = StateNotifierProvider<CartNotifier, List<CartItem>>((ref) {
return CartNotifier();
});
3. Consuming Providers
class ProductListPage extends ConsumerWidget {
const ProductListPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final asyncProducts = ref.watch(productsProvider);
return asyncProducts.when(
data: (products) => ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) => ProductCard(product: products[index]),
),
loading: () => const CircularProgressIndicator(),
error: (error, stack) => Text('Error: $error'),
);
}
}
4. Family & AutoDispose
// Family — parameterized provider
final productByIdProvider = FutureProvider.family<Product, String>((ref, id) async {
return ref.watch(productRepositoryProvider).getById(id);
});
// AutoDispose — cleanup khi không còn listener
final searchProvider = FutureProvider.autoDispose.family<List<Product>, String>((ref, query) async {
ref.keepAlive(); // Giữ cache cho đến khi dispose thủ công
return ref.watch(productRepositoryProvider).search(query);
});
Next article: Bloc Pattern & Cubit.