Reputation: 18758
I have a StatelessWidget
that uses a ScopedModel
to store its data. The widget basically presents a list of checkboxes and some buttons to save the state of the checked boxes.
Now I want to keep track of if the user has altered any of the checkboxes, i.e. checked/unchecked them since the widget was displayed. So I added something like this:
class MyCheckboxScreen extends StatelessWidget{
bool _hasBeenModified = false;
void _itemCheckedChange(bool checked, MyModel model){
_hasBeenModified = true;
// Code to change the model here
}
void _onCloseButton(){
if( _hasBeenModified ){
// Show a warning that there are modifications that will not be be saved
}
}
void _onSaveButton(Context context, MyModel model){
model.save();
Navigator.of(context).pop();
}
}
This seems to work, but my StatelessWidget
now contains its own state.
The state isn't used to update the UI and redraw anything, it's only used to check if there are modifications to any checkbox when pressing the "Close" button.
Is it safe for a StatelessWidget
to have this kind of internal state? Or could it be a problem? For example, could the widget be recreated unexpectedly, and the internal state lost?
I don't find the documentation to be very clear on this, it just says
For compositions that can change dynamically, e.g. due to having an internal clock-driven state, or depending on some system state, consider using StatefulWidget.
But this sounds like it only applies to state that affects the UI and requires rebuilding the widget.
Upvotes: 1
Views: 1834
Reputation: 4751
Yes, a StatelessWidget
can have mutable variables (your code compiles) but that's wrong.
A widget that does not require mutable state
This is taken from the documentation
. Even if you have a single non-final variable, it means that something can actually be changed in your widget. It's not an immutable class. Ideally, you should use StatelessWidget
s like this:
class MyWidget extends StatelessWidget {
final int a;
final String b;
const MyWidget(this.a, this.b);
}
Or something similar such as
class MyWidget extends StatelessWidget {
const MyWidget();
}
When you have non final variables, use a StatefulWidget
. Your class has to clearly be a StatefulWidget
:
// This is not final. It can be changed (and you will change it)
// so using the stateless way is wrong
bool _hasBeenModified = false;
void _itemCheckedChange(bool checked, MyModel model){
_hasBeenModified = true;
}
The UI doesn't matter actually because here's a matter of variables and mutability. Something is changing (bool _hasBeenModified
) so it cannot be a StatelessWidget
because it has to be used in all those cases where the state is immutable.
Upvotes: 6
Reputation: 647
Are there any reasons why you don't use a stateful widget? Stateless widgets aren't intended to be used that way.. And without any benefits, I don’t understand why you overcomplicate things..
Upvotes: 1