85

What does BuildContext do, and what information do we get out of it?

https://docs.flutter.dev/flutter/widgets/BuildContext-class.html is just not clear.

https://flutter.dev/widgets-intro/#basic-widgets on the 9th instance of the term BuildContext there is an example, but it's not clear how it is being used. It's part of a much larger set of code that loses me, and so I am having a hard time understanding just what BuildContext is.

Can someone explain this in simple/very basic terms?

Michael Ekoka
  • 19,050
  • 12
  • 78
  • 79
richalot
  • 4,491
  • 7
  • 24
  • 27

2 Answers2

111

BuildContext is, like it's name is implying, the context in which a specific widget is built.

If you've ever done some React before, that context is kind of similar to React's context (but much smoother to use) ; with a few bonuses.

Generally speaking, there are 2 use cases for context :

  • Interact with your parents (get/post data mostly)
  • Once rendered on screen, get your screen size and position

The second point is kinda rare. On the other hand, the first point is used nearly everywhere.

For example, when you want to push a new route, you'll do Navigator.of(context).pushNamed('myRoute').

Notice the context here. It'll be used to get the closest instance of NavigatorState widget above in the tree. Then call the method pushNamed on that instance.


Cool, but when do I want to use it ?

BuildContext is really useful when you want to pass data downward without having to manually assign it to every widgets' configurations for example ; you'll want to access them everywhere. But you don't want to pass it on every single constructor.

You could potentially make a global or a singleton ; but then when confs change your widgets won't automatically rebuild.

In this case, you use InheritedWidget. With it you could potentially write the following :

class Configuration extends InheritedWidget {
  final String myConf;

  const Configuration({this.myConf, Widget child}): super(child: child);

  @override
  bool updateShouldNotify(Configuration oldWidget) {
    return myConf != oldWidget.myConf;
  }
}

And then, use it this way :

void main() {
  runApp(
    new Configuration(
      myConf: "Hello world",
      child: new MaterialApp(
        // usual stuff here
      ),
    ),
  );
}

Thanks to that, now everywhere inside your app, you can access these configs using the BuildContext. By doing

final configuration = context.inheritFromWidgetOfExactType(Configuration);

And even cooler is that all widgets who call inheritFromWidgetOfExactType(Configuration) will automatically rebuild when the configurations change.

Awesome right ?

Zwenn
  • 5
  • 2
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • 1
    Thank you. Just to clarify, you mentioned that it allows you to interact with your parents. In your example, it seems like the BuildContext is interacting with the children of the widget that contains the BuildContext. Am I seeing this correctly? – richalot Mar 05 '18 at 01:33
  • 1
    It's the children that uses _their_ context to request their parent's info. – Rémi Rousselet Mar 05 '18 at 01:37
  • 1
    Any way to access said InheritedWidget outside of the build() method? no context. If I want to use the data, say in initState()? – Jus10 Apr 22 '18 at 16:08
  • 2
    you need context to access it. But you have access to context inside `initState`. – Rémi Rousselet Apr 22 '18 at 16:18
  • 5
    How in `initState`? every time I type `context` I get red squiggly lines :) – Jus10 Apr 29 '18 at 18:37
  • 1
    @Jus10 It shouldn't be the case. You can still get the `context` however it will not be a valid `BuildContext` because the `build()` hasn't run yet. – CopsOnRoad Jan 19 '19 at 14:30
  • 2
    Actually, the edit was unnecessary. the OP's original sentence was correct(not *"...widgets' configurations for example..."*, rather *"...widgets. Configurations for example..."* ). Also, `inheritFromWidgetOfExactType` is now deprecated, so use `yourContext.dependOnInheritedWidgetOfExactType();` – starriet Jan 19 '21 at 03:02
  • Thanks for this answer. But also I need to understand a lifecycle of a BuildContext. Is in context for one build or it is for all builds? When an instance of it is creating and when it destroyed? Can be context, obtained in one call of build, stored and used somewhere later? Can the context be recreated? When? – Nashev May 16 '23 at 06:41
  • UPD: in a page https://api.flutter.dev/flutter/widgets/BuildContext-class.html we have seen note to not store and not use after async gaps (but allow use with check mounted if apropriate) and see that context is an Element. At page https://api.flutter.dev/flutter/widgets/Element-class.html we have Element's lifecycle – Nashev May 16 '23 at 06:57
19

what is the BuildContext object/context?

Before we knowing about BuildCotext, We have to know about the Element object.

What is Element object

(note: As a flutter developer we never worked with Element object, but we worked with an object(known as BuildContext object) that's similar to Element object)

The Element object is the build location of the current widget.

What's really mean by "build location" ?

  1. when the framework builds a widget object by calling its constructor will correspondingly need to create an element object for that widget object.
  1. And this element object represents the build location of that widget.
  1. This element object has many useful instance methods.

Who uses the Element object and its methods ?

They are 02 parties that use the Element object and its methods.

  1. Framework (To create RenderObject tree etc)
  2. Developers (Like us)

What is BuildContext object ?

BuildContext objects are actually Element objects. The BuildContext interface is used to discourage direct manipulation of Element objects.

So BuildContext object = discouraged element object (That contains less number of instance methods compared to the original Element object)

Why framework discouraged the Element object and pass it to us ?

Because Element object has instance methods that must only be needed by the framework itself. but what happens when we access these methods by us, It's something that should not be done. So that the reason why framework discouraged the Element object and pass it to us



Ok Now let's talk about the topic

What does BuildContext object do in Flutter ?

BuildContext object has several useful methods to easily perform certain tasks that need to be done in the widget tree.

  1. findAncestorWidgetOfExactType().

    Returns the nearest ancestor widget of the given type T.

  2. findAncestorStateOfType().

    Returns the State object of the nearest ancestor StatefulWidget.

  3. dependOnInheritedWidgetOfExactType().

    Obtains the nearest widget of the given type T, which must be the type of a concrete InheritedWidget subclass, and registers this build context with that widget such that when that widget changes. [Used by Provider package]

The above methods are mostly used instance methods of BuildContext object if you want to see all the methods of that BuildContext object visit this LINK + see @remi Rousselot's answer.

dilshan
  • 2,045
  • 20
  • 18