I'm new to Flutter and I'm having an issue understanding how states work.
I've setup a page in my app as a StatefulWidget and then inside the sate for that page one of the main components is a separate StatefulWidget.
The inner widget shows a question and allows the user to enter an answer.
What I then wanted to do was show the next answer on the same page.
I have my inner widget callback to my page state once the answer has been entered.
I attempted to replace my inner widget with another copy, however the state is not reset. That is a new state is not created and initState() is never called again.
Is there a specific call or method I should be using to achieve this?
Edit: so for example if I had the following
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState(){
changeContent();
}
Widget innerWidget;
void changeContent(){
setState((){
innerWidget = new CustomStatefullWidget();
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
innerWidget
],
),
),
);
}
}
Here CustomStatefullWidget
is a class I've created as a stand alone interactive part of the page. The actual content shouldn't matter for this example.
What I had expected was that whenever changeContent()
was called then the innerWidget would have a new state but that isn't the case. The state for that is already stored in the tree and isn't refreshed when a new instance of the widget is created.
How can I force flutter to clear that part of the tree or recognize I want the state reset?
That is the expected behavior. When a parent rebuild flutter compare the new widget tree to the old one.
This way, flutter is able to know which widgets got "updated" and which got added/removed.
For added widgets, it'll create a new state. initState
is called. For updated widgets ; flutter will reuse the old widget and call didUpdateWidget
by passing as parameter the old "widget" part as parameter. As for removed widget, it'll call dispose
.
In your case, you expected that initState
would be called once again. But in fact it got "updated".
From this point you have two solutions to reset the state :
Implement a didUpdateWidget
. Which would reset your state or do whatever else you want.
This is the optimal approach, which you should consider. As you don't necessarily want to reset the children of your "new statefulwidget".
There's also the "lazy" solution, which is to tell flutter "Hey, this is a different widget. don't reuse the old one". That is achieved using Key
.
More info in key usage here
That would be as simple as changing your changeContent
method to the following:
Widget innerWidget;
void changeContent(){
setState((){
innerWidget = new CustomStatefullWidget(key: new UniqueKey());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With