Menu
CoddyTech

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.

challenge icon

Desafío

Fácil

Walk 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'),
            ),
          ],
        ),
      ),
    );
  }
}
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