¿Qué es el `BuildContext` en Flutter y para qué se usa?
Ver respuesta — intenta responderla en voz alta primero
El BuildContext es una referencia a la ubicación de un widget dentro del árbol. Sirve para que un widget encuentre a sus ancestros (como el Theme, el Navigator o un Provider) y para operaciones que dependen de dónde está el widget en el árbol. Cada widget tiene su propio BuildContext.
Cuando Flutter llama a build(BuildContext context), te da un context que representa "dónde estoy" en el árbol de widgets. Con él puedes:
- Buscar hacia arriba datos heredados:
Theme.of(context),MediaQuery.of(context),Navigator.of(context). - Acceder a un
ProvideroInheritedWidgetancestro. - Navegar entre pantallas.
Técnicamente, el BuildContext es el Element asociado al widget. Lo importante es entender que apunta a una posición en el árbol, no al widget en abstracto.
import 'package:flutter/material.dart';
class Ejemplo extends StatelessWidget {
const Ejemplo({super.key});
@override
Widget build(BuildContext context) {
// Uso el context para leer datos de ancestros del árbol
final colores = Theme.of(context).colorScheme;
final ancho = MediaQuery.of(context).size.width;
return ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: colores.primary),
onPressed: () {
// El context también sirve para navegar
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const OtraPantalla()),
);
},
child: Text("Ancho: $ancho"),
);
}
}
class OtraPantalla extends StatelessWidget {
const OtraPantalla({super.key});
@override
Widget build(BuildContext context) => const Scaffold();
}
Usar un context que ya no es válido o que está en el lugar equivocado del árbol. Un caso clásico: guardar el context y usarlo después de un await cuando el widget ya se desmontó (error "don't use BuildContext across async gaps"). Otro: intentar usar Scaffold.of(context) con el context del widget que crea el Scaffold, cuando ese context está por encima del Scaffold y no lo encuentra; la solución suele ser un Builder para obtener un context más abajo.
"El
BuildContextrepresenta la posición de un widget dentro del árbol. Lo uso para acceder a datos que vienen de ancestros, comoTheme.of(context),MediaQuery.of(context)o unProvider, y para navegar conNavigator.of(context). Técnicamente es elElementdel widget. Un cuidado importante es no usar uncontextdespués de unawaitsi el widget ya pudo desmontarse, porque elcontextya no sería válido."
¿Por qué a veces necesitas envolver algo en un Builder para obtener un context distinto?
Ver respuesta
Porque .of(context) busca hacia arriba en el árbol desde ese context. Si el ancestro que buscas (por ejemplo, el Scaffold) se crea dentro del mismo build, el context de ese método está por encima de él y no lo encuentra. Un Builder crea un nuevo context más abajo en el árbol, ya por debajo del Scaffold, así que Scaffold.of(context) sí lo localiza.