I am trying Flutter for the first time, and I am a little confused by the MultiProvider
class.
The question is straightforward, but I didn't find an explanation:
when should one use
Consumer
and whencontext.watch
?
For instance, taking one of the examples apps I have found, I tried using two providers for two global states, the theme and the status of the app:
runApp(
MultiProvider(providers: [
ChangeNotifierProvider(create: (context) => AppTheme()),
ChangeNotifierProvider(create: (context) => AppStatus()),
],
child: const MyApp()
));
Then the app widget accesses the theme with Consumer
:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<AppTheme>(
builder: (context, appTheme, child) {
// ...
As far as I understand, now all children widgets will inherit the provider. Is it right?
My home page, then, called by the MyApp
class does not use Consumer
, but context.watch
:
@override
Widget build(BuildContext context) {
final appTheme = context.watch<AppTheme>();
final appStatus = context.watch<AppStatus>();
return NavigationView(
// ...
It works, don't get me wrong, but I just copied the row above my appStatus
, so I don't really fully understand it. This is also due to another screen that I've concocted to access the AppStatus
global state, but I use Consumer
, as suggested by the Flutter documentation:
class _ViewerState extends State<Viewer> {
@override
Widget build(BuildContext context) {
return Consumer<AppStatus>(
builder: (context, appStatus, child) {
return ScaffoldPage.scrollable(
header: const PageHeader(title: Text('Test')),
children: [
FilledButton(child: Text("Try ${appStatus.count}"), onPressed: (){ appStatus.increment(); debugPrint('pressed ${appStatus.count}'); }),
FilledButton(child: Text("Reset"), onPressed: (){ appStatus.reset(); }),
]);
},
);
}
}
I have the feeling that I am misusing something here, and I do not really understand what's going on under the hood...
context.watch<T>()
and Consumer<T>
does the same thing. Most of the time context.watch<T>()
is just more convenient. In some cases where context
is not available Consumer<T>
is useful.