Menu
CoddyTech

Provider: compartir un modelo

Parte de la sección Gestión del estado del Journey de Flutter de Coddy. Lección 9 de 27.

Elevar el estado funciona mientras los widgets están cerca. Cuando se necesita un valor en toda la aplicación, en dos pantallas, en la barra superior o en lo más profundo de una lista, tendrías que pasarlo por cada widget intermedio. Provider evita eso. Es un paquete: un conjunto de código que importas con import 'package:provider/provider.dart';.

Tiene tres partes. Primero, un modelo: una clase que contiene los datos y extends ChangeNotifier. Sus métodos cambian los datos y luego llaman a notifyListeners():

class CupCounter extends ChangeNotifier {
  int _cups = 0;
  int get cups => _cups;

  void addCup() {
    _cups++;
    notifyListeners();
  }
}

Segundo, un ChangeNotifierProvider en un nivel alto del árbol crea el modelo una vez y se lo proporciona a todos los widgets que están debajo:

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CupCounter(),
      child: const MyApp(),
    ),
  );
}

Tercero, cualquier widget que esté debajo lo solicita: context.watch<CupCounter>() para mostrarlo, context.read<CupCounter>() para llamar a un método. El título y el botón de abajo reciben el mismo contador, y no se les pasa nada a ninguno de los dos.

challenge icon

Desafío

Intermedio

Abre la aplicación: muestra un error, porque el título solicita un CupCounter y nada por encima se lo proporciona.

  • En main, envuelve MyApp en un ChangeNotifierProvider que cree un CupCounter.

Pruébalo tú mismo

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class CupCounter extends ChangeNotifier {
  int _cups = 0;

  int get cups => _cups;

  void addCup() {
    _cups++;
    notifyListeners();
  }
}

void main() {
  runApp(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) {
    return Scaffold(
      appBar: AppBar(title: const CupsTitle()),
      body: const Center(child: AddCupButton()),
    );
  }
}

class CupsTitle extends StatelessWidget {
  const CupsTitle({super.key});

  @override
  Widget build(BuildContext context) {
    final counter = context.watch<CupCounter>();
    return Text('Cups: ${counter.cups}');
  }
}

class AddCupButton extends StatelessWidget {
  const AddCupButton({super.key});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        context.read<CupCounter>().addCup();
      },
      child: const Text('Another cup'),
    );
  }
}
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