Issue
From https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments it appears the preferred way of getting the arguments from a route is using:
ModalRoute.of(context)!.settings.arguments;
But since it requires the context argument it must be called inside the build method:
Widget build(BuildContext context) {
String id = ModalRoute.of(context)!.settings.arguments as String;
var data = httpGet(id);
return Scaffold(
//...
);
}
This means that every time the widget is rebuilt, the route argument will be refetched all over again and possibly another network call too.
The obvious solution is to have a boolean like wasFetched somewhere and add a conditional inside the build method.
Are most people doing the latter?
Edit:
Based on the first reply be @miguel-ruivo, I learned that context can actually be accessed as a property on the State object, and therefore accessible from initState.
In the end I went down the rabbit hole and found that I could call it from didChangeDependencies without needing to use addPostFrameCallback from WidgetsBindings.instance.
According to: https://api.flutter.dev/flutter/widgets/State/didChangeDependencies.html
It says:
This method is also called immediately after initState. It is safe to call BuildContext.dependOnInheritedWidgetOfExactType from this method.
Some subclasses do override this method because they need to do some expensive work (e.g., network fetches) when their dependencies change, and that work would be too expensive to do for every build.
And since it says dependOnInheritedWidgetOfExactType is safe to call, it would follow that anything dependent on BuildContext is safe to call.
So now I have put the code inside it:
didChangeDependencies() {
String id = ModalRoute.of(context)!.settings.arguments as String;
//do http
}
Solution
You can call it only once per widget initialisation by moving it to your initState() and scheduling a post frame so it only accesses BuildContext after rendering.
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(() {
String id = ModalRoute.of(context)!.settings.arguments as String;
var data = httpGet(id);
});
}
Answered By - Miguel Ruivo
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.