Menu
CoddyTech

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.

challenge icon

Tantangan

Sedang

Bilah atas mengamati totalMinutesProvider, tetapi provider itu selalu mengembalikan 0.

  • Buat bilah atas mengamati workoutsProvider dan mengembalikan jumlah minutes dari 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')),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pengelolaan State

Latihan sendiri: Compiler Flutter online