Provider: Consumer
Parte de la sección Gestión del estado del Journey de Flutter de Coddy. Lección 12 de 27.
Aquí, el proveedor se crea dentro del propio build de MyApp, y ese mismo build solicita la lámpara justo debajo. La aplicación muestra un error: context pertenece a MyApp, que está por encima del proveedor, y un widget solo puede encontrar proveedores que estén por encima de él.
Un Consumer lo soluciona. Es un widget, así que está debajo del proveedor, y su builder recibe un context nuevo y el modelo en sí:
Consumer<Lamp>(
builder: (context, lamp, child) {
return Text(lamp.isOn ? 'On' : 'Off');
},
)El builder se ejecuta de nuevo cada vez que la lámpara llama a notifyListeners(), como un widget que la observa. Dentro de él, puedes llamar a los métodos del modelo directamente sobre lamp: onPressed: () => lamp.toggle().
Un Consumer también reconstruye solo lo que envuelve, así que envolver la parte que cambia mantiene el resto de la pantalla sin cambios. En la mayoría de las aplicaciones usarás context.watch en un widget propio, y recurrirás a Consumer cuando estés en el mismo build que el proveedor.
Desafío
IntermedioLa aplicación se abre con un error. Coloca las partes de la lámpara dentro de un Consumer:
- Envuelve el
Columnen unConsumer<Lamp>y devuelve elColumndesde su constructor. - Dentro, usa el
lampdel constructor para el icono, el texto y el botón.
Pruébalo tú mismo
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Lamp extends ChangeNotifier {
bool _isOn = false;
bool get isOn => _isOn;
void toggle() {
_isOn = !_isOn;
notifyListeners();
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Lamp(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const Text('Lamp')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
context.watch<Lamp>().isOn ? Icons.lightbulb : Icons.lightbulb_outline,
size: 96,
color: context.watch<Lamp>().isOn ? Colors.amber : Colors.grey,
),
Text(context.watch<Lamp>().isOn ? 'The lamp is on' : 'The lamp is off'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => context.read<Lamp>().toggle(),
child: const Text('Switch'),
),
],
),
),
),
),
);
}
}
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