diegoRodicio

Está documentación está a túa disposición sin ningún custo económico. Sen embargo, para a súa elaboración dedico moito tempo e recursos, polo que agradecería unha colaboración co que consideres oportuno. Gracias.

View Categories

🧪 Xestión de Estado con `Provider`

🧩 Que é Provider? #

Provider é unha das solucións máis recomendadas para xestionar estado en Flutter de forma eficiente, modular e reactiva. Está construída sobre InheritedWidget, pero ofrece unha API moito máis sinxela e potente.

✅ Vantaxes de usar Provider #

  • 🔀 Separación clara entre lóxica de estado e interface de usuario.
  • 🌍 Estado global compartido entre diferentes widgets da árbore.
  • 🔁 Reactivo: só se reconstrúen os widgets que consumen datos modificados.
  • 🧠 Fácil de aprender: ideal para comezar en Flutter.
  • Eficiente: grazas a InheritedWidget, reconstrúe só o necesario.
  • 🔧 Flexible: funciona con calquera tipo de obxecto (non só ChangeNotifier).
  • 🤝 Gran comunidade e documentación.
  • 🚀 Bo rendemento: evita reconstrucións innecesarias.

📌 Características #

Provider é amplamente utilizado na comunidade Flutter, especialmente para aplicacións pequenas e medianas. A súa popularidade débese á súa:

  • Simplicidade
  • Flexibilidade
  • Eficiencia

Está construído sobre os InheritedWidget de Flutter, pero encapsulado dunha forma moderna e accesible.

🤔 É a mellor opción? #

Depende das túas necesidades. Non hai unha única “mellor” solución, pero Provider é un excelente punto de partida e cobre a gran maioría de casos.

⚖️ Provider vs setState #

setState é a forma máis básica de xestión de estado en Flutter. Ideal para widgets que teñen estado local e simple. Por exemplo:

📌 Se o estado só afecta ao propio widget ou a fillos inmediatos, usa setState.

En cambio, Provider é máis axeitado para:

  • Compartir estado entre diferentes pantallas ou widgets
  • Xestionar lóxica de negocio por separado da UI
  • Aplicacións máis complexas ou de maior tamaño

🧪 Exemplo con setState #

🔗 Ver o código en DartPad

📌 Cando usar setState ou Provider #

SituciónUsa setStateUsa Provider 📦
Estado local ao widget 
Cambio que afecta só ao widget ou a fillos directos 
Lóxica sinxela 
Estado compartido entre múltiples widgets non relacionados 📦
Separación entre UI e lóxica de negocio 📦
Aplicación mediana ou grande 📦
Precisas reconstruír só partes concretas da UI eficientemente 📦

⚙️ Instalación #

Engade provider ao teu pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.5 # Usa a versión máis recente dispoñible

⚠️ Importante: Despois de gardar o ficheiro, executa flutter pub get no teu terminal para descargar o paquete.

🧬 Estrutura básica de Provider #

Para empregar Provider nunha app Flutter, seguimos estes pasos fundamentais:

  1. Modelo de estado: Crear unha clase que estenda ChangeNotifier.
    Esta clase conterá os datos e métodos que queres compartir.

  2. Proporcionar o estado á árbore de widgets mediante ChangeNotifierProvider.
    Isto adoita facerse preto do widget raíz (por exemplo directamente no main()).

  3. Ler, modificar, escoitar e acceder ao estado usando métodos como context.watch<T>(), context.read<T>() ou o widget Consumer<T>().

🧰 Métodos para acceder ao estado #

MétodoUso recomendadoExemplo
context.watch<T>()🔄 Escoita os cambios do provedor e reconstrúe o widget automaticamente cando o estado cambia. Úsase dentro do método build().final contador = context.watch<Contador>();
context.read<T>()🔹 Lée o estado unha unica vez sen escoitar cambios. Ideal para chamadas únicas, fóra do método build(), por exemplo, nun onPressed.context.read<Contador>().incrementar();
Consumer<T>(...)🎯 Widget que reconstrúe só a parte necesaria da UI cando o estado cambia.Consumer<Contador>(builder: (_, c, __) => Text('${c.valor}'))
Provider.of<T>(context)⚠️ Obsoleto en moitos casos. Non se recomenda.

💡 Nota: Consumer é útil cando queres optimizar o rendemento e evitar que todo o widget se reconstrúa. Ideal para widgets anidados con partes independentes.

🧪 Exemplo: contador con Provider #

1️⃣ Definir o estado: Modelo #

import 'package:flutter/material.dart';

class Contador extends ChangeNotifier {
  int _valor = 0;

  int get valor => _valor;

  void incrementar() {
    _valor++;
    notifyListeners(); // notifica os widgets que escoitan
  }
}

2️⃣ Proporcionar o estado #

import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; // Importa o paquete provider

// Asegúrate de ter a clase Contador definida como no paso 1
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (contexto) => Contador(),
      child: AplicacionContador(),
    ),
  );
}

3️⃣ Modificar o estado. Interface de usuario que escoita #

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

// Asegúrate de ter a clase Contador definida

class AplicacionContador extends StatelessWidget {
  @override
  Widget build(BuildContext contexto) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Contador con Provider')),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextoContador(),
            BotonIncrementar(),
          ],
        ),
      ),
    );
  }
}

class TextoContador extends StatelessWidget {
  @override
  Widget build(BuildContext contexto) {
    final contador = context.watch<Contador>();
    return Text('Valor actual: ${contador.valor}', style: TextStyle(fontSize: 24));
  }
}

class BotonIncrementar extends StatelessWidget {
  @override
  Widget build(BuildContext contexto) {
    final contador = context.read<Contador>();
    return ElevatedButton(
      onPressed: contador.incrementar,
      child: Text('Incrementar'),
    );
  }
}

📚 Fontes de información #