Which is better when using provider instance in a new widget?

150

Solution 1

Prefer the first solution, it's easier to refactor.

Suppose you need move NewWidget in your widget tree, you also need to modify the "paramter pass" code if you choose second solution, which is not necessary with first solution.

One of Provider pacakage's purpose is avoid passing parameter deep in the widget tree by the way.

Solution 2

Depend on preference not like first or second one.

Have an exception when obtaining Providers inside initState. What can I do? This exception happens because you're trying to listen to a provider from a life-cycle that will never ever be called again.

It means that you either should use another life-cycle (build), or explicitly specify that you do not care about updates.

As such, instead of:

initState() {
  super.initState();
  print(context.watch<Foo>().value);
}

you can do:

Value value;

Widget build(BuildContext context) {
  final value = context.watch<Foo>.value;
  if (value != this.value) {
    this.value = value;
    print(value);
  }
}

which will print value whenever it changes (and only when it changes).

Alternatively, you can do:

initState() {
  super.initState();
  print(context.read<Foo>().value);
}

SRC: https://github.com/rrousselGit/provider#i-have-an-exception-when-obtaining-providers-inside-initstate-what-can-i-do

Solution 3

Yes, I believe the first option is the better way, of the top of my head I can't think of any situation in which you would prefer the second option to the first.

Share:
150
Jinsub Kim
Author by

Jinsub Kim

Updated on January 02, 2023

Comments

  • Jinsub Kim
    Jinsub Kim over 1 year

    Let's say I've written my code as below. I've got a provider called SampleProvider, and I'm using it in my main widget.

    class SampleProvider extends ChangeNotifier {}
    
    class MainWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        SampleProvider provider = Provider.of<SampleProvider>(context);
      }
    }
    

    And then, I want to make a new widget and use this provider in the new widget. There will be two choices. First, I just instantiate another provider in the new widget as below.

    class NewWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        SampleProvider provider = Provider.of<SampleProvider>(context);
      }
    }
    

    Or, I can send it from the main widget to the new widget as a constructor parameter. Like this:

    class NewWidget extends StatelessWidget {
      final SampleProvider provider;
      NewWidget(this.provider);
    
      @override
      Widget build(BuildContext context) {
      }
    }
    

    I guess the first option is better because flutter draws a widget based on its build context, but I'm not sure. I've googled it quite long, but there was no success. Can anybody tell me whether I am right or wrong? Or Do they have no difference?

  • Community
    Community over 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.