Provider: Obserwować czy odczytywać
Część sekcji Zarządzanie stanem ścieżki Flutter w Coddy. Lekcja 11 z 27.
Istnieją dwa sposoby pobierania modelu z Provider i każdy z nich służy do czegoś innego.
context.watch<StepCounter>() pobiera model i subskrybuje go: gdy model wywoła notifyListeners(), ten widżet zostanie ponownie zbudowany. Używaj go w build do wszystkiego, co wyświetla ekran.
context.read<StepCounter>() pobiera model jeden raz, bez subskrypcji. Używaj go w funkcjach zwrotnych, takich jak onPressed, gdy chcesz wywołać metodę, a nie wyświetlać cokolwiek:
Widget build(BuildContext context) {
final steps = context.watch<StepCounter>().steps; // wyświetla
return ElevatedButton(
onPressed: () => context.read<StepCounter>().walk(), // wykonuje działanie
child: Text('$steps steps'),
);
}Pomylić je i od razu widać różnicę. read w build wyświetla pierwszą wartość na zawsze. watch wewnątrz onPressed powoduje błąd, ponieważ kliknięcie nie jest budowaniem widżetu i nie ma czego subskrybować.
Wyzwanie
ŁatwyWalk dodaje 1000 kroków do modelu, ale na ekranie nadal widnieje 0 steps.
- Spraw, aby wiersz z liczbą kroków odzwierciedlał model, tak by po każdym dotknięciu wyświetlała się nowa liczba.
- Pozostaw wywołanie przycisku bez zmian.
Spróbuj swoich sił
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class StepCounter extends ChangeNotifier {
int _steps = 0;
int get steps => _steps;
void walk() {
_steps += 1000;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => StepCounter(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final steps = context.read<StepCounter>().steps;
return Scaffold(
appBar: AppBar(title: const Text('Steps')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('$steps steps', style: const TextStyle(fontSize: 40)),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
context.read<StepCounter>().walk();
},
child: const Text('Walk'),
),
],
),
),
);
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Zarządzanie stanem
3Provider
Provider: Udostępnianie modeluWywoływanie notifyListenersProvider: Obserwować czy odczytywaćProvider: ConsumerDwa ekrany, jeden modelLista obiektów w modeluWiele modeli: MultiProviderPoćwicz samodzielnie: Kompilator Flutter online