Is Provider.of(context, listen: false) equivalent to context.read()?
Asked Answered
U

3

15
// Are these the same?
final model = Provider.of<Model>(context, listen: false); 
final model = context.read<Model>(); 

// Are these the same?
final model = Provider.of<Model>(context);
final model = context.watch<Model>();

Are they the same or aren't they? If they are, then why do I get this error when I use read inside the build() method, while Provider.of() works?

Tried to use context.read<Model> inside either a build method or the update callback of a provider.

Ulric answered 8/6, 2020 at 7:30 Comment(0)
U
17

Well, they aren't the same.

You shouldn't use read inside the build method. Instead stick to the old is gold pattern:

final model = Provider.of<Model>(context, listen: false); 

read is used when you want to use the above pattern in a callback, for instance, when a button is pressed, then we can say they both are performing the same action.

onPressed: () {
  final model = context.read<Model>(); // recommended
  final model = Provider.of<Model>(context, listen: false); // works too
}
Ulric answered 12/6, 2020 at 16:4 Comment(2)
now it would be interesting to know, why does the documentation recommend against using context.read() in a build method ....Chavey
@Chavey In this answer, Remi explains why context.read must not be used in build method. But I must say that I'm not convinced by it.Fungosity
S
35

final model = context.read<Model>();
This returns the Model without listening for any changes.

final model = context.watch<Model>();
This makes the widget listen for changes on the Model.

final model = Provider.of<Model>(context, listen: false);
This works the same as context.read<Model>();

final model = Provider.of<Model>(context);
This works the same as context.watch<Model>();

Recommendations:
Use context.read(), context.watch() instead of Provider.of(). For more insights, refer to this, this & this.

Shelbashelbi answered 11/6, 2020 at 17:47 Comment(6)
I am sure you must have read the question carefully before answering. -1 from me, sorry!!!Ulric
The default value of listen = true when you do not specify in Provider.of(). If you want to get updated data, you must use a "watch" instead or "read".Shelbashelbi
First, I didn't ask about the default value of listen, second, I didn't want to get the updated data. I again suggest you to read the question carefully before answering. ThanksUlric
I didn't though. Can you kindly share any example what you want to achieve and what you are getting currently? It seems the question can lead to some misunderstanding. If possible!Shelbashelbi
Well I am currently using FirebaseAuth as my model, when I use Provider.of(...) with listen: false, it works but when I use read, it fails.Ulric
I have added my own answer, you can take a look now.Ulric
U
17

Well, they aren't the same.

You shouldn't use read inside the build method. Instead stick to the old is gold pattern:

final model = Provider.of<Model>(context, listen: false); 

read is used when you want to use the above pattern in a callback, for instance, when a button is pressed, then we can say they both are performing the same action.

onPressed: () {
  final model = context.read<Model>(); // recommended
  final model = Provider.of<Model>(context, listen: false); // works too
}
Ulric answered 12/6, 2020 at 16:4 Comment(2)
now it would be interesting to know, why does the documentation recommend against using context.read() in a build method ....Chavey
@Chavey In this answer, Remi explains why context.read must not be used in build method. But I must say that I'm not convinced by it.Fungosity
C
4

context.read<T>() internally returns Provider.of<T>(context, listen: false).

For the moment, use whichever you think is best or the one you prefer.

This is the implementation of read in Provider:

extension ReadContext on BuildContext {
  T read<T>() {
    return Provider.of<T>(this, listen: false);
  }
}
Cygnet answered 3/8, 2021 at 16:28 Comment(1)
This should be the accepted answer as it directly address OP's question.Superior

© 2022 - 2024 — McMap. All rights reserved.