Flutter: diferencia entre setState y Provider en State Management

En este artículo, veremos cómo podemos usar la gestión de estado o el paquete de proveedores para implementar la gestión de estado en nuestra aplicación Flutter. 

Estamos creando una aplicación de contador simple en flutter, que nos ayudará a comprender la administración del estado en la aplicación flutter y decidir cuál es una mejor manera de construir nuestra aplicación y completar el proyecto.

Discutiremos los dos aspectos más importantes necesarios para comprender la gestión de estado en la aplicación flutter, llamados setState y un paquete llamado proveedor.

Empezando

Comenzaremos con nuestra estructura básica de aleteo disponible por defecto. Cree un widget sin estado llamado Página de inicio y asígnelo a nuestra propiedad de inicio de Material App.

Dart

import 'package:flutter/material.dart';
  
void main() => runApp(MyApp());
   
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Material App',
        home: HomePage()
      );
  }
}

Estructura de nuestra aplicación

Dentro de la pantalla ‘ Página de inicio ‘, lo convertiremos en un widget con estado, y constará de dos botones que tendrán la funcionalidad de aumentar y disminuir el contador usando la funcionalidad de estado establecido. Y un botón de acción flotante que nos llevará a la segunda pantalla de nuestra aplicación, donde nuevamente se mantendrá el seguimiento de nuestra variable itemCount .

Dart

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
  
class _HomePageState extends State<HomePage> {
  int itemCount = 0 ;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.forward),
        onPressed: (){
          Navigator.push(context, MaterialPageRoute(builder: (_){
            return SecondPage(
              count: itemCount,
            );
          }));
        },
      ),
      body: Column(
        children: [
          Container(
            alignment: Alignment.center,
            height: 300.0,
            child: Text('$itemCount',style: TextStyle(fontSize: 30.0)),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              ElevatedButton(onPressed: (){
                setState(() {
                  itemCount++ ; 
                });
              }, child: Text('Add')),
              ElevatedButton(onPressed: (){
                setState(() {
                  itemCount-- ; 
                });
              }, child: Text('Delete'))
            ],
          )
        ],
      ),
    );
  }
}

Dentro de la segunda pantalla, tendremos nuevamente los botones para el contador creciente y decreciente. con la ayuda de la funcionalidad de estado establecida  

Será un widget con estado.

Dart

class SecondPage extends StatefulWidget {
  int count ;
  SecondPage({this.count}) ;
  
  @override
  _SecondPageState createState() => _SecondPageState();
}
  
class _SecondPageState extends State<SecondPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          Container(
            alignment: Alignment.center,
            height: 300.0,
            child: Text('${widget.count}',style: TextStyle(fontSize: 30.0)),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              ElevatedButton(onPressed: (){
                setState(() {
                  widget.count++ ;
                });
              }, child: Text('Add')),
              ElevatedButton(onPressed: (){
                setState(() {
                  widget.count-- ;
                });
              }, child: Text('Delete'))
            ],
          )
        ],
      ),
    );
  }
}

Al ejecutar con éxito nuestro código, podemos ver que no obtenemos el resultado deseado. La variable de contador no obtiene su valor correcto.

Producción 

Entonces, para superar este problema y mejorar las funcionalidades dentro de nuestra aplicación, usaremos el paquete del proveedor. Es de gran utilidad cuando tenemos que lidiar con una aplicación de múltiples pantallas donde nuestros datos cambian dinámicamente, el proveedor nos brinda una mejor facilidad para mantener nuestros datos actualizados con cada función de nuestra aplicación. 

Primero importe la dependencia del proveedor dentro del archivo pubspec.yam l en nuestra aplicación flutter. 

Ahora cree una clase en otro archivo, extienda esta clase a Change Notifier. Esta clase contendrá funcionalidades de aumento y disminución de la variable contador. No olvide incluir notificar a los oyentes sobre nuestra función; de lo contrario, no funcionará correctamente. Además, cree un captador que devolverá la variable de conteo. 

Dart

import 'package:flutter/material.dart';
  
class Manage extends ChangeNotifier{
    int count = 0 ;
  
    int get counter{
      return count ; 
    }
  
    void increaseCounter(){
      count++ ;
      notifyListeners();
    }
  
     void decreaseCounter(){
        count-- ;
        notifyListeners();
     }
}

Para que nuestra aplicación sea consciente y conozca a los proveedores, debemos agregar algo a nuestra aplicación Material dentro de main.dart. Envuelva nuestra aplicación Material. Dentro de la función MultiProvider y dentro de ella, agregue nuestra clase a la opción de proveedores de Multi Provider.  

Dart

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: Manage())
      ],
          child: MaterialApp(
        home: HomePage(),
      ),
    );
  }
}

Ahora la tarea final y restante es actualizar algo en la pantalla de nuestra página de inicio para que pueda escuchar a nuestro proveedor. 

Primero, haga que la página de inicio sea un widget sin estado. 

Dart

class HomePage extends StatelessWidget {
     
  @override
  Widget build(BuildContext context) {
    int itemCount = Provider.of<Manage>(context).counter;
  
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.forward),
        onPressed: (){
          Navigator.push(context, MaterialPageRoute(builder: (_){
            return SecondPage();
          }));
        },
      ),
      body: Column(
        children: [
          Container(
            alignment: Alignment.center,
            height: 300.0,
            child: Text('$itemCount',style: TextStyle(fontSize: 30.0)),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              ElevatedButton(onPressed: (){
                Provider.of<Manage>(context,listen:false).increaseCounter();
              }, child: Text('Add')),
              ElevatedButton(onPressed: (){
                Provider.of<Manage>(context,listen:false).decreaseCounter();
              }, child: Text('Delete'))
            ],
          )
        ],
      ),
    );
  }
}

Asegúrese de hacer que el valor del argumento de escucha sea falso dentro del proveedor utilizado para llamar a las funciones. Lo haremos realidad solo cuando tengamos que usar el valor o escuchar el valor en la pantalla de nuestra aplicación. (Como el valor de itemCount)

Del mismo modo, podemos actualizar nuestro widget de segunda página en consecuencia. Conviértalo en un widget sin estado 

Dart

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
   int itemCount  = Provider.of<Manage>(context).counter ; 
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          Container(
            alignment: Alignment.center,
            height: 300.0,
            child: Text('$itemCount',style: TextStyle(fontSize: 30.0)),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              ElevatedButton(onPressed: (){
                Provider.of<Manage>(context,listen: false).increaseCounter();
              }, child: Text('Add')),
              ElevatedButton(onPressed: (){
                Provider.of<Manage>(context,listen: false).decreaseCounter();
              }, child: Text('Delete'))
            ],
          )
        ],
      ),
    );
  }
}

Producción 

Por lo tanto, podemos ver que el proveedor hace nuestro trabajo bastante bien y es fácil de usar. 

Publicación traducida automáticamente

Artículo escrito por 19uec032 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *