I used provider in my project and I fond a strange trigger mechanism.
Widget build(BuildContext context) {
final notifer = Provider.of<Notifier>(context);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
When I push a new page, I noticed that the first page's provider was touched off, but no notifyListeners was called. And when I pop the second page, the first page's provider was touched off again, still no notifyListeners was called. If I removed the
final notifer = Provider.of<Notifier>(context);
then the Widget will not refresh every time I push or pop.
Could you share a minimal reproduction repository?
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class Notifier with ChangeNotifier {}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Notifier>(
builder: (context) => Notifier(),
child: MaterialApp(
title: 'Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final notifer = Provider.of<Notifier>(context);
print("refresh");
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => MySecondHomePage()));
},
child: Icon(Icons.add),
),
);
}
}
class MySecondHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("second Page"),
),
body: Container(),
);
}
}
For a StatefulWidget, widget will refresh when we do push or pop action. For a StatelessWidget, push or pop action should not make widget refresh. But in this case, an empty provider will make a StatelessWidget refresh every push or pop action.
Indeed. That's intriguing.
At first glance, I don't see any reason behind this.
After a quick test, this is unrelated to provider.
I replaced the Provider.of<Notifier>(context) with a Theme.of(context) and the problem still happens.
Digging a step deeper, I converted MyFirstHomePage into a StatefulWidget to override both deactivate and didChangeDependencies.
It seems that pushing routes calls deactivate on all other routes.
This, in turn, rebuilds _all_ widgets that depend on an InheritedWidget.
Nice catch, but I can't do anything about it. It's an issue on Flutter's end.
Most helpful comment
After a quick test, this is unrelated to
provider.I replaced the
Provider.of<Notifier>(context)with aTheme.of(context)and the problem still happens.Digging a step deeper, I converted
MyFirstHomePageinto aStatefulWidgetto override bothdeactivateanddidChangeDependencies.It seems that pushing routes calls
deactivateon all other routes.This, in turn, rebuilds _all_ widgets that depend on an
InheritedWidget.Nice catch, but I can't do anything about it. It's an issue on Flutter's end.