Provider: observar o leer
Parte de la sección Gestión del estado del Journey de Flutter de Coddy. Lección 11 de 27.
Hay dos formas de obtener un modelo de Provider, y cumplen funciones diferentes.
context.watch<StepCounter>() obtiene el modelo y se suscribe a él: cuando el modelo llama a notifyListeners(), este widget se vuelve a construir. Úsalo en build para cualquier cosa que muestre la pantalla.
context.read<StepCounter>() obtiene el modelo una vez, sin suscribirse. Úsalo en devoluciones de llamada como onPressed, donde quieres llamar a un método y no mostrar nada:
Widget build(BuildContext context) {
final steps = context.watch<StepCounter>().steps; // muestra
return ElevatedButton(
onPressed: () => context.read<StepCounter>().walk(), // actúa
child: Text('$steps steps'),
);
}Si los confundes, lo notarás. read en build muestra el primer valor para siempre. watch dentro de onPressed es un error, porque un toque no es una construcción y no hay nada a lo que suscribirse.
Desafío
FácilWalk añade 1000 pasos al modelo, pero la pantalla sigue mostrando 0 steps.
- Haz que la línea de pasos siga el modelo, para que cada toque muestre el nuevo número.
- Mantén la llamada del botón tal como está.
Pruébalo tú mismo
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'),
),
],
),
),
);
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Gestión del estado
Practica por tu cuenta: Compilador de Flutter online