¿Qué opciones de gestión de estado conoces en Flutter y cuándo usarías cada una?
Ver respuesta — intenta responderla en voz alta primero
Las más comunes son: setState para estado local, Provider para estado compartido sencillo, Riverpod como evolución de Provider más segura y testeable, y Bloc/Cubit para lógica de negocio basada en eventos y estados bien definidos. No hay una "mejor": depende del tamaño del proyecto y de la complejidad del estado.
El "estado" es cualquier dato que cambia y afecta la UI. La pregunta clave es quién necesita ese dato:
setState: estado local de un widget (un contador, un toggle). Simple y suficiente para lo que vive en un solo widget.Provider: expone objetos a un subárbol y notifica cambios (usaChangeNotifier+notifyListeners()). Bueno para estado compartido de apps pequeñas y medianas. Construido sobreInheritedWidget.Riverpod: parecido a Provider pero sin depender delBuildContextpara leer, con mejor seguridad de tipos y más fácil de testear. Muy popular en proyectos nuevos.Bloc/Cubit: separa la lógica de la UI mediante eventos que entran y estados que salen. Escala bien en apps grandes y equipos, a costa de más código.
Regla: empieza simple (setState) y sube de nivel solo cuando el estado compartido y la complejidad lo justifiquen.
import 'package:flutter/material.dart';
// Patrón ChangeNotifier (la base de Provider)
class ContadorModel extends ChangeNotifier {
int _cuenta = 0;
int get cuenta => _cuenta;
void incrementar() {
_cuenta++;
notifyListeners(); // avisa a los widgets que escuchan
}
}
// En un proyecto real, con el paquete provider, se usaría así:
//
// ChangeNotifierProvider(
// create: (_) => ContadorModel(),
// child: MiApp(),
// );
//
// Y dentro de un widget:
// final modelo = context.watch<ContadorModel>();
// Text('${modelo.cuenta}');
// onPressed: () => context.read<ContadorModel>().incrementar();
Meter toda la app en un solo estado global gigante o, al revés, usar una librería pesada como Bloc para una app de dos pantallas. También es común llamar a notifyListeners() de más (reconstruyendo la UI innecesariamente) o modificar el estado sin notificar (la UI no reacciona). Elige la herramienta según la complejidad real, no por moda.
"Para estado local uso
setState. Cuando el estado se comparte entre varios widgets, usoProvider, que se apoya enChangeNotifierynotifyListenersy por debajo usaInheritedWidget. En proyectos nuevos me gustaRiverpodporque es más seguro en tipos, no depende delcontextpara leer y es más fácil de testear. Y para apps grandes con lógica de negocio compleja,BlocoCubit, que separan la UI de la lógica con eventos y estados. Mi criterio es empezar simple y subir de nivel solo cuando la complejidad lo pide."
En el patrón ChangeNotifier, ¿qué pasa si cambias un valor pero olvidas llamar a notifyListeners()?
Ver respuesta
El valor cambia en memoria, pero los widgets que escuchan no se enteran y no se reconstruyen: la UI se queda mostrando el dato viejo. notifyListeners() es lo que dispara la actualización de todos los oyentes. Es el equivalente conceptual a olvidar el setState.