Optimización de reconstrucción para OverlayEntries y Routes
Los OverlayEntries solo se reconstruyen ante cambios explícitos de State.
Resumen
#Esta optimización mejora el rendimiento de las transiciones de rutas,
pero podría revelar llamadas faltantes a setState en tu aplicación.
Contexto
#Antes de este cambio, un OverlayEntry se reconstruía cuando
se añadía una nueva entrada opaca encima de él o se eliminaba por encima.
Estas reconstrucciones eran innecesarias porque no eran provocadas
por un cambio de State en el OverlayEntry afectado. Este
cambio importante optimizó cómo manejamos la adición y eliminación de
OverlayEntrys y elimina reconstrucciones innecesarias
para mejorar el rendimiento.
Dado que Navigator coloca internamente cada Route dentro de un
OverlayEntry, este cambio también se aplica a las transiciones de Route:
si se inserta una Route opaca encima o se elimina por encima de otra
Route, las Routes por debajo de la Route opaca
ya no se reconstruyen innecesariamente.
Descripción del cambio
#En la mayoría de los casos, este cambio no requiere modificaciones en tu código.
Sin embargo, si tu aplicación dependía erróneamente de las
reconstrucciones implícitas, es posible que veas problemas, que se pueden resolver
envolviendo cualquier cambio de State en una llamada a setState.
Además, este cambio modificó ligeramente la estructura del
árbol de widgets: antes de este cambio,
los OverlayEntrys estaban envueltos en un Widget Stack.
El Widget Stack explícito fue eliminado de la jerarquía de widgets.
Guía de migración
#Si ves problemas después de actualizar a una versión de Flutter
que incluye este cambio, audita tu código en busca de llamadas faltantes a
setState. En el siguiente ejemplo, asignar el valor de retorno de
Navigator.pushNamed a buttonLabel modifica
implícitamente el State y debería envolverse en una
llamada a setState explícita.
Código antes de la migración:
class FooState extends State<Foo> {
String buttonLabel = 'Click Me';
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () async {
// Illegal state modification that should be wrapped in setState.
buttonLabel = await Navigator.pushNamed(context, '/bar');
},
child: Text(buttonLabel),
);
}
}
Código después de la migración:
class FooState extends State<Foo> {
String buttonLabel = 'Click Me';
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () async {
final newLabel = await Navigator.pushNamed(context, '/bar');
setState(() {
buttonLabel = newLabel;
});
},
child: Text(buttonLabel),
);
}
}
Timeline
#Lanzado en la versión: 1.16.3
En versión estable: 1.17
Referencias
#Documentación de la API:
Issues relevantes:
PRs relevantes:
A menos que se indique lo contrario, la documentación de este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 2026-05-05. Ver código fuente oreportar un problema.