Gestión de estados en Flutter ¿Qué es? ¿Cómo puedo aplicarlo?

Daniel Herrera Sánchez
Bancolombia Tech
Published in
7 min readApr 24, 2022

¡Oh sí! estamos por fin entrando a temas un poco más avanzados como comunidad. En este blog les hemos compartido desde temas sencillos como el manejo de scrollable widgets hasta temas más avanzados como arquitectura limpia en Flutter. Deberías suscribirte si no lo has hecho, porque lo que se viene son temas cada vez más interesantes que los anteriores. En nuestra última entrega para Flutter publicamos un artículo que nos aclaraba qué es Provider y Christian nos dejó este comentario:

Su inquietud es muy buena, porque en algunos foros nos comentaban que Provider es un gestor de estados, pero como vimos en el último artículo no es así; su versatilidad hace que la utilicen para ese fin, pero no es su razón de ser.

Entonces, ¿qué es realmente la gestión de estados y cómo podemos implementarla? En este artículo espero que aclares todas tus dudas y estemos listos para que en nuestras aplicaciones siempre tengamos una gestión de estados.

Nota importante: lee antes el artículo que explica provider para una mayor comprensión (enlace).

¿Qué es la gestión de estados?

Comencemos por definir qué es un estado. La RAE lo define como “situación o modo de estar de una persona o cosa, en especial la situación temporal de las personas o cosas cuya condición está sujeta a cambios”.

Si llevamos esta definición a una aplicación, podríamos decir que, el estado describe la situación actual de la aplicación o de sus componentes. Por ejemplo, el solo hecho de que el usuario le dé clic a un checkbox cambia la situación actual de la aplicación, por tanto cambia su estado.

Otro ejemplo, podría ser cuando hacemos una petición a una API en el back. Mientras estamos cargando la información mostramos un indicador circular y, cuando la información está lista, mostramos los datos recibidos en pantalla de forma que tendríamos el estado loading (cargando) y el estado loaded (cargado).

En la práctica, existen al menos dos tipos de estado determinantes dentro de las aplicaciones que debes conocer; los estados efímeros y de aplicación. Veamos cada uno de ellos:

Estados efímeros

El estado efímero (a veces llamado estado de UI o estado local ) es el estado que puede contener perfectamente un solo widget. Por ejemplo:

  • Pestaña seleccionada actual en un BottomNavigationBar
  • CheckBox Seleccionado
  • Un Botón accionado

Con esto en mente, debemos pensar para al estado efímero no necesitan acceder los demás widgets en el árbol.

Estado de aplicación

Este estado no es efímero, es necesario compartirlo a lo largo de la aplicación y en ocasiones desea mantenerlo entre sesiones de usuario (a veces también llamado estado compartido).

Ejemplos de estado de aplicación:

  • Preferencias del usuario
  • Estado de autenticación
  • El carrito de compras en una aplicación de comercio electrónico

Ahora que sabemos de este tipo de estados hagamos el siguiente mapa mental, para saber cuando estamos ante un estado de aplicación o un estado efímero:

Gestor de Estados

Los gestores estados nos ayudarán a hacer la administración de las interacciones de los clientes en nuestras aplicaciones. 🧐 No es necesario utilizar estrategias complejas para la gestión de estados efímeros, puedes usar en este escenario los habituales State y setState para su administración. Esto se debe a que su alcance está encapsulado en el widget y nadie mas lo requiere en el árbol de widgets. (enlace)

Para administrar los estados de aplicación si es mejor utilizar una estrategia, que te permita administrar de forma sencilla los mismos. ¿Deseas ver un ejemplo? Eso lo veremos en el siguiente 🥲… apartado (no pienses que te haremos esperar a otro artículo 🤣).

Ejemplo de Gestión de estados

Bueno vamos a iniciar a ver la teoría aplicada al código.

Administrando un estado efímero

Esto ya lo has visto, de hecho en el hola mundo de Flutter :

Cuando el usuario da clic sobre el botón, aumenta el contador y esto genera un aumento en el número, y redibuja el texto relacionado al mismo. Cómo se observa en la función _incrementCounter se utiliza un setState. ¿Esto significa que elemento está implementado con malas prácticas? por supuesto que no.

En este escenario, nadie más en la aplicación utilizará el valor de este contador, si el alcance del estado está encapsulado en el widget no es necesario implementar una estrategia más avanzada.

Administrando el estado de la aplicación

Planteemos el siguiente escenario :

Hagamos una aplicación sencilla. Tendrá tres pantallas, una donde el cliente ingresará el usuario y contraseña, otra donde se hará una petición a una API para obtener una lista de álbumes para que el usuario seleccione cuáles desea comprar y, por último, una pantalla de compra de los elementos seleccionados.

Este ejemplo me gusta mucho, porque nos permite crear estados efímeros y de aplicación. Antes de mostrar código pensemos en los estados de aplicación, ¿cuáles crees que serían?

En este caso hablaremos de los siguientes: Usuario autenticado y lista de álbumes seleccionados por el cliente. Sin embargo, ¿se te ocurren algunos estados efímeros? Piensa por ejemplo en el controlador del campo de texto y sus estados, o en los botones que únicamente ejecuten instrucciones en su contexto.

Ahora pensemos en lo siguiente, en el artículo anterior donde explicamos el uso de Provider, nos quedó claro que lo utilizamos para compartir información a lo largo del árbol de widgets. Por eso, resulta muy útil para manejar los estados de la aplicación (pues necesitas acceder a una variable de estado desde cualquier lugar de nuestra aplicación).

Sin embargo pensemos en el nombre del usuario ¿es un estado de la APP? por supuesto que no. Pero es información relevante que nos gustaría compartir a lo largo de nuestro árbol de widgets y podemos utilizar Provider para compartirla. Inclusive también podríamos utilizar Provider para la inyección de dependencias.

Ahora sí, vamos al código🧑🏽‍💻.

Vamos primero por los Providers :

user_provider: Proveedor de información relacionada al usuario. En este escenario el provider se esta utilizando para compartir información relevante (línea 5,6,7) y para gestionar estado de la sesión (línea 4,7,12).

cart_provider: En este escenario tenemos el proveedor de nuestro carrito de compras. Ante el cambio en la lista de compras se notifica a todos sus hijos. Y así debe ser pues la cantidad de productos y su información hacen parte del estado de nuestra app de compras.

album_provider: Este es un proveedor que no está haciendo gestión de estados. Únicamente se esta empleando para hacer inyección de dependencias y compartirlo a lo largo del árbol de widgets.

app.dart : Si notamos en las líneas 21–29 se configura nuestros proveedores. En la linea 23 se hace la inyección de dependencia, en caso que se deseara un mock en vez de la API allí se podría configurar.

login_page: En la línea 14 se inicia el controlador del input, pero en la línea 24 se inicia una referencia al providerUser lo que permite al momento de presionar el botón (línea 53) se actualice el estado y la información del usuario (líneas 54,55).

Luego esta información puede ser accedida desde cualquier widget en nuestra aplicación.

Ahora veamos la gestión de la lista de compras:

Como notan el estado del checkbox no lo estamos administrando desde el provider (aunque sí se podría hacer, ¿te animas a hacer un fork y hacerlo? 🤓), pero si estamos registrando lo más importante, a saber : remover o adicionar el elemento a nuestra lista de compras y el estado actual del elemento (seleccionado o no seleccionado).

Te dejo como actividad que revises el repositorio en este enlace y puedas observar todo los elementos de la aplicación ejemplo.

Conclusión

Espero que con este artículo quedemos más tranquilos en lo referente a gestión de estados, que entendamos las diferencias entre estado efímero y de aplicación; y que te animes a utilizarlo en todas tus soluciones. Recibe un fuerte abrazo y si te gustó este artículo danos +50 aplausos por favor.

Nos vemos en una próxima entrega 🧐. Cuéntanos en la caja de comentarios que te gustaría que analicemos en el próximo artículo.

--

--

Daniel Herrera Sánchez
Bancolombia Tech

Flutter,Dart@GoogleDevExpert💙 • 🔴Youtube Channel Weincode •👨🏻‍💻FlutterMedellin Community Lead • 🙅🏻‍♂️Angular Content creator • Speaker •GitHub: weincoder