I have an ArticlesPage widget, which has a periodic timer to route the same page again. This is a way to pull in new articles from external API.
To avoid having too many pages in the screen stack, I pop all other pages using Navigator.of(context).popUntil((route) => route.isFirst);
in the build method.
During the periodic routing, I keep seeing the following error:
Unhandled Exception: setState() called after dispose(): _ArticlesPageState#9ae77(lifecycle state: defunct, not mounted) E/flutter (19115): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree
How should I fix it?
The ArticlesPage widget:
class ArticlesPage extends StatefulWidget {
ArticlesPage({Key key}) : super(key: key);
@override
_ArticlesPageState createState() => _ArticlesPageState();
}
class _ArticlesPageState extends State<ArticlesPage> {
void __refresh() {
Navigator.of(context).push(slideRouteArticles());
}
@override
void initState() {
super.initState();
new Timer.periodic(
Duration(seconds: 5),
(Timer t) => setState(() {
__refresh();
}));
}
@override
Widget build(BuildContext context) {
//pop all other pages
Navigator.of(context).popUntil((route) => route.isFirst);
return Scaffold(
drawer: MenuDrawerStatefulWidget(),
appBar: MyAppBar(),
body: RefreshIndicator(
onRefresh: () async {
__refresh();
},
child: Container(
color: BG_COLOR,
padding: EdgeInsets.fromLTRB(LR_SPACE, 20, LR_SPACE, 0),
child: ArticleListStatefulWidget(key: UniqueKey())),
),
);
}
}
The slideRouteArticles function:
Route slideRouteArticles() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => ArticlesPage(key: UniqueKey(),),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 0),
end: Offset.zero,
).animate(animation),
child: child,
);
},
);
}
The best solution I found for myself was to make sure that the widget IS in the Widget Tree by running this code:
if (this.mounted){
setState((){
//Your state change code goes here
});
}
Original answer to the question of setState() called after dispose()