Flutter · One codebase, native feel
What is BuildContext and what are its pitfalls?
Short answer
BuildContext is a handle to a widget's location in the element tree. It gives access to inherited data, theme, media query and navigation, and it becomes invalid when the element is deactivated.
BuildContext is implemented by Element. Calling Theme.of or MediaQuery.of registers a dependency on an InheritedWidget, so the widget rebuilds when that data changes. Navigator.of, ScaffoldMessenger.of and GoRouter.of use the same lookup mechanism.
Future<void> openProfile(BuildContext context) async {
final theme = Theme.of(context);
final navigator = Navigator.of(context);
final profile = await api.fetchProfile();
if (!context.mounted) return;
navigator.push(
MaterialPageRoute(builder: (_) => ProfilePage(profile: profile)),
);
debugPrint(theme.colorScheme.primary.toString());
}- Look up dependencies in build or didChangeDependencies, not in initState
- After an await, check context.mounted before using the context
- Capture Navigator or ScaffoldMessenger before the await when appropriate
- Never store a BuildContext in a long-lived object
- A context above MaterialApp cannot find a Navigator or Theme from below it
Why context can become invalid
When a route is popped or a widget is removed, its element is deactivated. Calling an inherited lookup with that context throws or returns stale results. The mounted check prevents the common use-after-dispose failure after async navigation.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why can you not use Theme.of in initState?
- 2What does context.mounted protect against?
- 3How does an InheritedWidget dependency trigger rebuilds?
- 4What happens if you call Navigator.of with the context above MaterialApp?
Say it in the interview
BuildContext is the element's location in the tree. It is how I read inherited data like theme, media query and localizations, and how I reach the navigator or scaffold messenger. The main pitfall is using it after the element is deactivated, especially after an await. I capture what I need before async work and check context.mounted before touching the context again.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Flutter mock interview and get scored feedback on depth, clarity and confidence.