flutterdartstateinherited-widget

Get InheritedWidget parameter in initState


i need some help understanding how to obtain data from inherited widget.

I usually get the parameter from my widget directly from the build method using

  @override
  Widget build(BuildContext context) {    
   //THIS METHOD
   var data = StateContainer.of(context).data;

   return Container(child:Text("${data.parameter}"));
  }

But this method cant be called from initState since there is no buildContext yet.

I need in the initState method to have that parameter (i call my fetch from server in that and i need to pass that data to my function), so, how should i do it?

@override
void initState() {
 otherData = fetchData(data);
 super.initState();
}

I tried using didChangeDipendencies() but it is called every time the view is rebuilt (popping from screen, etc.) so it is not what i want to use and neither the FutureBuilder widget.

Any suggestion?


Solution

  • First, note that you probably do want to use didChangeDependencies. But you can't just do your call there without any check. You need to wrap it in an if first.

    A typical didChangeDependencies implementation should look similar to:

    Foo foo;
    
    @override
    void didChangeDependencies() {
      super.didChangeDependencies();
      final foo = Foo.of(context);
      if (this.foo != foo) {
        this.foo = foo;
        foo.doSomething();
      }
    }
    

    Using such code, doSomething will be executed only when foo changes.


    Alternatively, if you are lazy and know for sure that your object will never ever change, there's another solution.

    To obtain an InheritedWidget, the method typically used is:

    BuildContext context;
    InheritedWidget foo = context.inheritFromWidgetOfExactType(Foo);
    

    and it is this method that cannot be called inside initState.

    But there's another method that does the same thing:

    BuildContext context;
    InheritedWidget foo = context.ancestorInheritedElementForWidgetOfExactType(Foo)?.widget;
    

    The twist is: - this method can be called inside initState - it won't handle the scenario where the value changed.

    So if your value never changes, you can use that instead.