Flutter: usar ENUM como estado de la App

Descubre cómo utilizar una estructura de programación tan simple como un Enum para gestionar el estado de una aplicación.
En mi artículo anterior hablamos de por qué es importante usar manejo de estados en una aplicación flutter. También explicamos cómo usar una entidad (un objeto con ID único) como estado y actualizar widgets de forma automática cuando esa entidad cambia.
Un poco de historia..
El paquete SPREAD debe su nombre al término anglosajón “spreadsheet”, el nombre original de las hojas de cálculo.
El término “hoja de cálculo” podría parecer extraño para aquellos que lo asocian únicamente con su capacidad digital. Sin embargo, “hoja de cálculo” es una referencia bastante literal a su forma original de hace cientos de años.
En aquel entonces, una hoja de cálculo era un libro de contabilidad lleno de grandes hojas de papel que, literalmente, se extendían sobre la mesa. Estas hojas estaban divididas en filas y columnas para ingresar datos manualmente con una pluma o lápiz.
La hoja de cálculo original lucía algo así:

hoja de cálculo en papel
Con el avance de la tecnología y la llegada de la era digital, las hojas de cálculo experimentaron una transformación revolucionaria. Las hojas de cálculo electrónicas comenzaron a surgir en la década de 1960 y 1970, pero fue en la década de 1980, con programas como VisiCalc y más tarde Lotus 1–2–3, cuando realmente ganaron popularidad. Microsoft Excel, lanzado en 1987, se convirtió en uno de los programas más dominantes y reconocidos en este ámbito, consolidando la transición de las hojas de papel a las pantallas de computadora.
La principal y obvia ventaja de las hojas de cálculo electrónicas es la automatización de cálculos: Una vez ingresada una fórmula, el programa puede realizar cálculos automáticamente, eliminando la necesidad de hacerlo manualmente. Si dicha formula depende de valores en otras celdas (las cuales a su vez pueden contener otras fórmulas) y estas celdas son modificadas, la fórmula dependiente se entera del cambio y ejecuta de nuevo la fórmula subyacente, mostrando en la cuadricula el nuevo resultado
Del mismo modo, si tenemos muchas celdas cuyas fórmulas dependen del valor de una única celda (la celda independiente), al cambiar el valor de esta última, todas las demás que dependen de ella se actualizan también de forma automática.
Desde el punto de vista de la programación, esto es un comportamiento reactivo. Las celdas dependientes estan suscritas a eventos de cambio provenientes de la celda independiente. Esto se hace al hacer referencia a otras celdas en una fórmula. Cuando un usuario modifica el valor de la celda independiente, las dependientes reaccionan automáticamente a dicho evento ejecutando nuevamente sus respectivas fórmulas.
Es justo este comportamiento reactivo de las hojas de cálculo electrónicas el que inspira la creación del paquete SPREAD, haciendo que los Widgets se suscriban a eventos de cambio de un único estado y re-dibujando el Widget solo cuando dicho estado es modificado, haciendo la aplicación más performante y el código fuente más escalable y desacoplado.
En este capítulo sobre Flutter y SPREAD veremos y probaremos en vivo cómo usar una estructura de programación tan simple como un enumerador para controlar el estado de una aplicación.
¿Qué es un ENUM?
Un Enum (abreviatura de “enumeration”, que significa enumeración en inglés) es una estructura de datos especial que permite representar un conjunto de valores constantes bajo un solo tipo. Estos valores son, por lo general, un conjunto limitado y relacionado de opciones.
Imagina que estás creando un videojuego y tienes diferentes tipos de armas. Podrías tener un Enum llamado “TipoDeArma” que contenga valores como “Espada”, “Arco”, “Lanza”, etc. En lugar de usar cadenas de texto o números para representar estas armas, puedes usar el Enum para hacer tu código más legible y menos propenso a errores.
enum TipoDeArma {
ESPADA,
ARCO,
LANZA
}
void main() {
TipoDeArma armaSeleccionada = TipoDeArma.ESPADA;
print(armaSeleccionada); // Salida: TipoDeArma.ESPADA
}
Ventajas de usar Enums
1. Legibilidad: Hace el código más fácil de leer al proporcionar nombres descriptivos para conjuntos de valores relacionados.
2. Seguridad: Reduce la posibilidad de errores al restringir las opciones a un conjunto limitado de valores.
3. Organización: Agrupa valores relacionados bajo un solo tipo, lo que facilita la gestión y el mantenimiento del código.
¿Cómo usar Enums para manejar estados?
Antes de empezar, te recomiendo ir a este link y podrás ver y probar el códigó fuente que explicaremos en este artículo gracias a Zapp.run, el cual contiene todo lo necesario para programar en Flutter sin necesidad de instalar nada en tu computadora.

- Crea tu Enum que representará el estado de tu app:
enum AppState { users, posts }
fuente aqui.
2. Crea un Widget para mostrar los usuarios cuando el estado sea AppState.users
import 'package:flutter/cupertino.dart';
import 'package:spread/spread.dart';
import '../states.dart';
class UsersPage extends StatelessWidget {
const UsersPage({super.key});
@override
Widget build(BuildContext context) =>
Spread<AppState>(builder: (BuildContext context, AppState? state) {
return Center(
child: Text(state?.toString() ?? "<USERS>"),
);
});
}
fuente aqui.
Este Widget contiene un Spread widget builder suscrito a cambios de estado de tipo AppState (nuestro enum). Solo dibujamos un Text con el String correspondiente al state.
3. Crea un Widget para mostrar los posts cuando el estado sea AppState.posts
import 'package:flutter/cupertino.dart';
import 'package:spread/spread.dart';
import '../states.dart';
class PostsPage extends StatelessWidget {
const PostsPage({super.key});
@override
Widget build(BuildContext context) =>
Spread<AppState>(builder: (BuildContext context, AppState? state) {
return Center(
child: Text(state?.toString() ?? "<POSTS>"),
);
});
}
fuente aqui.
Similar a Users, también dibujamos un Text con el String correspondiente al state.
4. Crea un Widget que presentará usuarios o posts dependiendo del estado actual
import 'package:flutter/material.dart';
import 'package:spread/spread.dart';
import 'widgets/posts.dart';
import 'widgets/users.dart';
import 'states.dart';
import 'config.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
SpreadState().emit<AppState>(AppState.users);
return Scaffold(
appBar: _appbar,
bottomNavigationBar: _navigator(context),
body: Spread<AppState>(
builder: _homeBody,
));
}
Widget _homeBody(BuildContext context, AppState? state) {
switch (state) {
case AppState.posts:
{
return const UsersPage();
}
case AppState.users:
default:
{
return const PostsPage();
}
}
}
BottomNavigationBar _navigator(BuildContext context) => BottomNavigationBar(
onTap: onNavigatorTap,
...
...
);
Future onNavigatorTap(int index) async {
print('navigator tap: $index');
switch (index) {
case 0:
{
SpreadState().emit<AppState>(AppState.users);
break;
}
case 1:
{
SpreadState().emit<AppState>(AppState.posts);
break;
}
}
}
}
fuente completo aqui.
La función build() crea un Scaffold cuyo body contiene un Spread widget builder suscrito a estados de tipo AppState.
La función _homeBody() es responsable de dibujar el body del scaffold a partir del resultado del SWITCH
La función onNavigatorTap() es responsable de emitir el estado dependiendo del TAB que fue activado.
¿Cómo funciona? al hacer click en un Tab, se emite un nuevo estado de tipo AppState. el Spread widget builder reacciona a este tipo de estado, provocando que solo el body se re-dibuje.

Puedes ver un demo de la app aqui.
Conclusión
El paquete SPREAD en Flutter se inspira en el comportamiento reactivo de las hojas de cálculo electrónicas, permitiendo que los Widgets se suscriban a eventos de cambio de un estado específico y se redibujen solo cuando ese estado cambia. Esta funcionalidad no solo mejora el rendimiento de la aplicación, sino que también hace que el código fuente sea más escalable y desacoplado. En este artículo, hemos explorado cómo utilizar una estructura de programación tan simple como un Enum para gestionar el estado de una aplicación. Los Enums no solo proporcionan legibilidad y organización al código, sino que también ofrecen seguridad al restringir las opciones a un conjunto limitado de valores. Al combinar la potencia de los Enums con la reactividad del paquete SPREAD, los desarrolladores pueden crear aplicaciones Flutter más eficientes y mantenibles.
Créditos de imágenes
- flutter spread logo: Diseño original de josegonp
- hoja de cálculo en papel: tomada de The history of spreadsheets