Reputation: 2271
I have the following variables
String _warningMessage;
bool _warningVisibility;
Which I want to update via a Class which implements an interface
class _UserSignupInterface extends _SignupSelectUsernamePageState
implements UserSignupInterface {
@override
void onSuccess() {
_hideWarning();
_navigateToUserPage();
}
@override
void onError(String message) {
_isSignupClickable = true;
if(message != null) {
_displayWarning(message);
}
}
}
with the _displayWarning code (which is inside the _SignupSelectUsernamePageState
)
void _displayWarning(String message) {
if (message != null) {
setState(() {
widget._warningMessage = message;
widget._warningVisibility = true;
});
}
}
However, whenever I call the _displayWarning(message)
from outside the _SignupSelectUsernamePageState
. I get an error saying
Unhandled Exception: setState() called in constructor
Is there a proper way of updating these variable states outside their class? Which in my case, I'm calling the _displayWarning(message)
from another class that implements an interface
Upvotes: 7
Views: 10735
Reputation: 647
Just create a static value in the state of your widget class, then when you build the widget, set it's value to the widget. So whenever you want to call it to setState()
, just call the static value.
Upvotes: -2
Reputation: 5780
You have to decide whether this is a value that is changed internally within the widget, or if that's a value that changes externally to it.
If it's internal, the common thing is to place them in the State
class with the _ on them, they could start with a value for instance set on initState
and every time they change you call setState
to indicate that.
However, if they change outside the widget, then you place them on the StatefulWidget
class (as you seem to have done), you leave them without the _ as they are actually public and you even make them final and place them in the constructor to allow them to be set.
In this last case, if in the State
class you must be aware of a change in the widget, you can implement didUpdateWidget
, but that's not mandatory.
Of course you can mix both things, having a _warningMessage
in the State
, so you can update it with setState
, but with an initial value defined in initState
that comes from the widget.
Again, if the widget changes externally, you can again update the value of the _warningMessage
with the new widgets value.
Something like that: (I didn't test this code)
class YourWidget extends StatefulWidget {
YourWidget({this.warningMessage});
final String warningMessage;
@override
State<YourWidget> createState() => new _YourWidgetState();
}
class _YourWidgetState extends State<YourWidget> {
String _warningMessage;
@override
void initState() {
super.initState();
_warningMessage = widget.warningMessage;
}
@override
didUpdateWidget(ReorderableListSimple oldWidget) {
super.didUpdateWidget(oldWidget);
_warningMessage = widget.warningMessage;
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(_warningMessage),
RaisedButton(
child: Text("Change Message"),
onPressed: () {
setState(() {
_warningMessage = "new message from within the State class";
});
}
)
],
);
}
}
So in this example you can change the warningMessage
externally, like in the parent
Widget you are able to pass a different message. However, if you need, you can also set it internally using setState
, as it's happening in the button's onPressed
.
What you might check is wether you actually need that property exposed in the Widget
, maybe you don't! Then, the example would look like that:
class YourWidget extends StatefulWidget {
@override
State<YourWidget> createState() => new _YourWidgetState();
}
class _YourWidgetState extends State<YourWidget> {
String _warningMessage;
@override
void initState() {
super.initState();
_warningMessage = "default message, no need for widget";
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(_warningMessage),
RaisedButton(
child: Text("Change Message"),
onPressed: () {
setState(() {
_warningMessage = "new message from within the State class";
});
}
)
],
);
}
}
Upvotes: 3