Provider yang Memantau Provider
Termasuk bagian Pengelolaan State dalam perjalanan Flutter di Coddy. Pelajaran 20 dari 27.
Sebagian state berasal dari state lain: total menit adalah jumlah seluruh latihan. Kamu bisa menjumlahkannya di setiap widget yang menampilkan total, atau menuliskannya sekali saja sebagai provider yang memantau provider lain:
final totalMinutesProvider = Provider((ref) {
final workouts = ref.watch(workoutsProvider);
return workouts.fold(0, (sum, w) => sum + w.minutes);
});Fungsi provider juga mendapatkan ref. Dengan ref.watch di dalamnya, Riverpod mengingat bahwa total bergantung pada latihan. Tambahkan latihan, lalu total dihitung lagi dan setiap widget yang memantau total dibangun ulang.
Gunakan ref.watch di sini, bukan ref.read. read mengambil list satu kali, saat total pertama kali dihitung, dan total tidak pernah berubah setelah itu.
Ini adalah gagasan getter dari sebelumnya, untuk seluruh aplikasi: simpan sesedikit mungkin, lalu hitung sisanya dari data tersebut.
Tantangan
SedangBilah atas mengamati totalMinutesProvider, tetapi provider itu selalu mengembalikan 0.
- Buat bilah atas mengamati
workoutsProviderdan mengembalikan jumlahminutesdari setiap workout.
Coba sendiri
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')),
],
),
),
],
),
);
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pengelolaan State
1Mengangkat State ke Atas
Kirim State ke Komponen AnakKirim Callback ke Komponen AnakCallback yang Mengirim NilaiAngkat State ke Atas4Riverpod
Riverpod: ProviderScopeConsumerWidget dan ref.watchRiverpod: StateProviderRiverpod: NotifierProvider yang Memantau ProviderMemilih Tempat State DisimpanLatihan sendiri: Compiler Flutter online