Menu
CoddyTech

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.

challenge icon

Desafío

Intermedio

La aplicación se abre con un error. Coloca las partes de la lámpara dentro de un Consumer:

  • Envuelve el Column en un Consumer<Lamp> y devuelve el Column desde su constructor.
  • Dentro, usa el lamp del 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'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
quiz iconPonte a prueba

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