Diğer Provider'ları İzleyen Provider'lar
Coddy'nin Flutter Journey'sinin Durum Yönetimi bölümünün bir parçası. Ders 20 / 27.
Bazı durumlar diğer durumlardan türetilir: toplam dakika, antrenmanların toplamıdır. Toplamı gösteren her widget'ta bunları toplayabilir ya da başka bir sağlayıcıyı izleyen bir sağlayıcı olarak bunu bir kez yazabilirsin:
final totalMinutesProvider = Provider((ref) {
final workouts = ref.watch(workoutsProvider);
return workouts.fold(0, (sum, w) => sum + w.minutes);
});Bir sağlayıcının işlevi de ref alır. İçinde ref.watch kullandığında Riverpod, toplamın antrenmanlara bağlı olduğunu hatırlar. Bir antrenman ekle; toplam yeniden hesaplanır ve toplamı izleyen her widget yeniden oluşturulur.
Burada ref.read yerine ref.watch kullan. read, listeyi yalnızca toplam ilk kez hesaplandığında alır ve sonrasında toplam hiç değişmez.
Bu, daha önceki getter fikrinin tüm uygulamaya uygulanmış hâlidir: olabildiğince az şeyi sakla ve geri kalanını bunlardan hesapla.
Görev
OrtaÜst çubuk totalMinutesProvider'ı izliyor, ancak bu sağlayıcı her zaman 0 döndürüyor.
workoutsProvider'ı izlemesini ve her antrenmanınminutesdeğerlerinin toplamını döndürmesini sağlayın.
Kendin dene
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class Workout {
Workout(this.name, this.minutes);
final String name;
final int minutes;
}
class WorkoutLog extends Notifier<List<Workout>> {
@override
List<Workout> build() => [];
void add(Workout workout) {
state = [...state, workout];
}
}
final workoutsProvider = NotifierProvider<WorkoutLog, List<Workout>>(WorkoutLog.new);
final totalMinutesProvider = Provider((ref) {
return 0;
});
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: LogPage(),
);
}
}
class LogPage extends ConsumerWidget {
const LogPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final workouts = ref.watch(workoutsProvider);
final total = ref.watch(totalMinutesProvider);
return Scaffold(
appBar: AppBar(title: Text('Total: $total min')),
body: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => ref.read(workoutsProvider.notifier).add(Workout('Run', 30)),
child: const Text('Run'),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () => ref.read(workoutsProvider.notifier).add(Workout('Yoga', 20)),
child: const Text('Yoga'),
),
],
),
Expanded(
child: ListView(
children: [
for (final w in workouts) ListTile(title: Text(w.name), trailing: Text('${w.minutes} min')),
],
),
),
],
),
);
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Durum Yönetimi bölümündeki tüm dersler
1State’i Üst Bileşene Taşıma
State’i Alt Bileşene AktarmaAlt Bileşene Bir Callback AktarmaDeğer Gönderen Callback’lerState’i Üst Bileşene Taşıma4Riverpod
Riverpod: ProviderScopeConsumerWidget ve ref.watchRiverpod: StateProviderRiverpod: NotifierDiğer Provider'ları İzleyen Provider'larState'in Nerede Tutulacağını SeçmekKendi başına pratik yap: Online Flutter derleyicisi