Currently, when I would like initial values of a stateful widget to be configurable, I follow a pattern that looks like
class MyWidget extends StatefulWidget {
final String? initialValue;
MyWidget({ this.initialValue });
@override State createState() => MyWidgetState();
}
class MyWidgetState extends State<MyWidget> {
String statefulValue = "default initial value";
@override
void initState() {
super.initState();
if (widget.initialValue != null) { statefulValue = widget.initialValue; }
}
// ...
}
This works, but seems a bit heavyweight to me to achieve something I have to think is a very common use case. First, it doesn't make sense to me that initialValue
should have to be a field at all, since its use is only to initialize the state, and then is no longer needed. Second, I think it would avoid some boiler plate if the state class could have a constructor that the stateful widget could call, so the above could look like:
class MyWidget extends StatefulWidget {
final String? initialValue;
MyWidget({ this.initialValue });
@override State createState() => MyWidgetState(initialValue: initialValue);
}
class MyWidgetState extends State<MyWidget> {
String statefulValue;
MyWidgetState({ String? initialValue }) : statefulValue = initialValue ?? "default initial value";
// ...
}
That doesn't exactly solve the first problem, but I think reads more easily. This however triggers the "Don't put any logic in createState"
linter error. So my questions are
a) is there a pattern where the initial value doesn't have to be held on to longer than necessary?
b) why is passing parameters to the State
constructor frowned upon?