Riverpod - إدارة حالة متقدمة — Flutter المتقدم
Riverpod - الجيل التالي من Provider
لماذا Riverpod؟
1. آمن من الأخطاء (Compile-time safe)
2. لا يحتاج BuildContext
3. قابل للاختبار بسهولة
4. دعم أفضل للـ async
1. الإعداد
dependencies:
flutter_riverpod: ^2.4.0void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}2. أنواع Providers
// Provider بسيط (قيمة ثابتة)
final greetingProvider = Provider<String>((ref) {
return 'مرحباً بالعالم!';
});
// StateProvider (قيمة متغيرة)
final counterProvider = StateProvider<int>((ref) => 0);
// StateNotifierProvider (منطق معقد)
class CounterNotifier extends StateNotifier<int> {
CounterNotifier() : super(0);
void increment() => state++;
void decrement() => state--;
void reset() => state = 0;
}
final counterNotifierProvider = StateNotifierProvider<CounterNotifier, int>((ref) {
return CounterNotifier();
});
// FutureProvider (بيانات async)
final userProvider = FutureProvider<User>((ref) async {
final response = await http.get(Uri.parse('https://api.example.com/user'));
return User.fromJson(jsonDecode(response.body));
});
// StreamProvider
final messagesProvider = StreamProvider<List<Message>>((ref) {
return chatService.messagesStream;
});3. استخدام Providers
// مع ConsumerWidget
class CounterScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Column(
children: [
Text('$count'),
ElevatedButton(
onPressed: () => ref.read(counterProvider.notifier).state++,
child: Text('زيادة'),
),
],
);
}
}
// مع hooks
class CounterScreen extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Text('$count');
}
}
// في StatelessWidget
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, ref, child) {
final count = ref.watch(counterProvider);
return Text('$count');
},
);
}
}4. FutureProvider مع UI
final productsProvider = FutureProvider<List<Product>>((ref) async {
final api = ref.watch(apiServiceProvider);
return api.getProducts();
});
class ProductsScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final productsAsync = ref.watch(productsProvider);
return productsAsync.when(
loading: () => Center(child: CircularProgressIndicator()),
error: (error, stack) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('خطأ: $error'),
ElevatedButton(
onPressed: () => ref.refresh(productsProvider),
child: Text('إعادة المحاولة'),
),
],
),
),
data: (products) => ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ProductCard(product: products[index]);
},
),
);
}
}5. Providers معتمدة على بعضها
final authProvider = StateProvider<User?>((ref) => null);
final userOrdersProvider = FutureProvider<List<Order>>((ref) async {
final user = ref.watch(authProvider);
if (user == null) return [];
final api = ref.watch(apiServiceProvider);
return api.getOrders(user.id);
});اختبر فهمك