Reputation: 28876
// 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 abuild
method or theupdate
callback of a provider.
Upvotes: 18
Views: 13686
Reputation: 379
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);
}
}
Upvotes: 7
Reputation: 2956
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.
Upvotes: 39
Reputation: 28876
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
}
Upvotes: 18