Understand Simple Flutter Basics: What Is BuildContext?

BuildContext is a handle to the location of a widget in the widget tree.

The first thing we learn in Flutter is that everything is a widget. Not just small components of the page like a form or a menu, but everything. A single button is a widget. A line of text is a widget. Padding and margins are also achieved with widgets. The whole widgets of a Flutter application are displayed in the form of a Widget Tree where we connect the parent and child widgets to show a relationship between them. So, here comes the role of BuildContext. We can use the BuildContext to locate a particular widget in a widget tree. Every widget has its own BuidContext. A particular BuildContext is associated with only one widget.

As we know that every widget in Flutter is created by the build method and the build method takes a BuildContext as an argument. This helps the build method to find which widget it is going to draw and also it helps in locating the drawing position of the widget in the widget tree. If some widget is having some children widgets then both the parent and the children will have their own BuildContext. Now, the BuildContext of the parent widget will be the parent of the BuildContext of its direct children widget.

Also, one thing to note here is that widgets are only visible to their BuildContext or to its parent’s BuildContext. So, from a child widget, we can locate the parent widget. For example, if the tree structure is: Scaffold > Center > Row > FlatButton, then we can get the first Scaffold from FlatButton by going up:

context.ancestorWidgetOfExactType(Scaffold)

We can also locate a child widget from a parent widget and for that, we use InheritedWidgets. This use-case of BuildContext can be used to pass some message form the parent to the child widget in the widget tree.

Every Flutter widget has an @override build() method with the argument of BuildContext.

class CartItemWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) {.....

Simple explanation is that the BuildContextin Flutter is:

  1. A BuildContext only belongs to one widget.
  2. BuildContext objects are passed to WidgetBuilder functions

A BuildContext only belongs to one widget.

If a widget ‘A’ has children widgets, the BuildContext of widget ‘A’ will become the parent BuildContext of the direct children BuildContexts.

Reading this, it is clear that BuildContexts are chained and are composing a tree of BuildContexts (parent-children relationship).

BuildContext objects are passed to WidgetBuilder functions (such as StatelessWidget.build), and are available from the State.context member. Some static functions (e.g. showDialog, Theme.of, and so forth) also take build contexts so that they can act on behalf of the calling widget, or obtain data specifically for the given context.

Each widget has its own BuildContext, which becomes the parent of the widget returned by the StatelessWidget.build or State.build function. (And similarly, the parent of any children for RenderObjectWidgets.)

In particular, this means that within a build method, the build context of the widget of the build method is not the same as the build context of the widgets returned by that build method. This can lead to some tricky cases. For example, Theme.of(context) looks for the nearest enclosing Theme of the given build context. If a build method for a widget Q includes a Theme within its returned widget tree, and attempts to use Theme.of passing its own context, the build method for Q will not find that Theme object. It will instead find whatever Theme was an ancestor to the widget Q. If the build context for a subpart of the returned tree is needed, a Builder widget can be used: the build context passed to the Builder.builder callback will be that of the Builder itself.

Things to Look out for:

We always needs to be careful while using BuildContext. We always need to verify that the context that we are using in the method is the same context that we need. For example, Theme.of(context) looks for the nearest Theme. So, if some widget A is having a Theme in its returned widget tree and it is calling Theme.of(passing its own context) then the build method of widget A will find whatever Theme was an ancestor to the widget A and it will not find the Theme present in the widget A. So, to get the BuildContext of the subpart of the tree, we can use the Builder widget and the context passed to the Builder widget will be the context of that Builder widget only.