Chuyển đến nội dung chính

第 6 課:使用 Riverpod 進行狀態管理

Provider vs Riverpod vs Bloc。 Riverpod 2.0:Provider、StateProvider、StateNotifierProvider、FutureProvider、StreamProvider。自動處置,系列修改器。代碼生成。

💻 程式設計 — 第 6 課 第 6 課:使用 Riverpod 進行狀態管理

Flutter 和 Dart:從基礎到高級

第 2 部分:導航和狀態管理

亞洲開發網

1. Riverpod 設定

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. 提供者類型

// 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. 消費提供者

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 — 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);
});

下一篇: 塊狀圖案和肘節。