'Does StatefulWidget not rebuild State every time it has new data?
The widget TrainsPage is added to the build graph in main.dart, when the corresponding menu button is clicked. This is done twice: once when _routes is empty and a second time when _routes is filled.
Widget pageSelector() {
if (_selectedIndex == 2) {
return new TrainsPage(routes: _routes);
} else
return Text("");
}
In TrainsPage.dart, I have the code for the stateful widget TrainsPage.
class TrainsPage extends StatefulWidget {
const TrainsPage({Key? key, required this.routes}) : super(key: key);
final List<RSRoute> routes;
@override
_TrainsPageState createState() => _TrainsPageState();
}
class _TrainsPageState extends State<TrainsPage> {
List<RSRoute> _routes = List.empty();
@override
void initState() {
super.initState();
this._routes = new List<RSRoute>.from(widget.routes);
Now, the second time, TrainsPage gets called in main.dart (now with routes filled), initState() of _TrainsPageState is not called, which is responsible to read the data in routes. And because routes was empty the first time, there is nothing in display on the trains page.
Why does TrainsPage not rebuild _TrainsPageState, when it clearly got new data in the constructor?
Solution 1:[1]
This is exactly why the State exists : to keep the state of the current context alive even when the widget is rebuild.
If it was recreated each time the statefull widget is rebuild it could not keep the state of its own variables.
class MyWidget extends StatelessWidget {
var _someStateVariable = 0;
@override
void build(BuildContext context){
// here an action that increment _someStateVariable
}
}
Here _someStateVariable would be reset to 0 at each rebuild. Or if we wanted a StateFullWidget in the first place it's because we'll update this variable later and want to keep its updated value through the multiple widget rebuilds. If you don't have such state variable to maintain maybe you don't need a StateFullWidget here.
Now to the solution to your problem : you can override didUpdateWidget instead of initstate since it will be called at each widget rebuild :
@override
void didUpdateWidget() {
didUpdateWidget();
_routes = new List<RSRoute>.from(widget.routes);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |