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.