My understanding of state management is that calling setState()
alone opens up a variety of messy issues, code files become huge and difficult to debug, and it prevents holding a sensible structure to a project. In cases where the widget's appearance changes slightly, it makes little sense to have a complex architecture like BLoC or ScopedModel just to show/hide a widget (for example). However, the way I have understood it is that you can't mix setState()
and an architecture together, otherwise what's the point of the architecture?
Let's use BLoC for this question (simply because I happen to be using it), specifically this package. Let's say I have this super simple example code:
class MyWidget extends StatefulWidget {
@override
void createState() {
return _MyWidgetState();
}
}
class _MyWidgetState extends State<MyWidget>() {
bool _isShowing = false;
MyBloc bloc;
@override
void initState() {
super.init();
bloc = MyBloc();
}
@override
Widget build(BuildContext context) {
return BlocBuilder(
bloc: bloc,
builder: (context, state) {
return Column(
children: <Widget>[
Text(state.myText),
if (_isShowing)
Text("Button has been pressed!"),
RaisedButton(
child: Text("Show label"),
onTap: () => setState(() => _isShowing = true),
),
RaisedButton(
child: Text("Run event"),
onTap: () => bloc.add(NewEvent()),
),
],
);
},
);
}
}
In the crude example above, is it right/acceptable to mix the BLoC pattern with setState()
? Why would I not use BLoC to handle showing the Text
widget? Where do I draw the line? What are the pros/cons? Is there a performance difference?
Note: I'm not looking for "just merge the two Text
widgets together" answers. I'm looking for purely architectural perspectives.
Having a solid BLoC architecture in place leads to a good separation of concerns. Although using the BLoC pattern requires more code than using setState, it makes the code more readable, scalable, and testable.
In Flutter, you can manage the state of your app just by using setState. But while setState can be your best friend, it’s not a good idea to depend on it solely.
This means more code, more things to keep track of and extending or adding new pieces of logic would require more setStates all over the place. Flutter provides a great way for us to handle all of this without needing to use a stateful widget and set state. All of the code above can be replaced by one widget.
BlocProvider is a Flutter widget that makes any BLoC available to the entire widget tree below it. In our case, any widget in between Home (top) and ProductTile (bottom) can have access to the cart, so no need to pass the cart data from the top of the widget tree to the bottom.
You can.
Architecture like scoped_model/bloc/etc aren't about removing calls to setState. They are about separating concerns and simplifying the implementation
You can and should use setState when it makes sense to use it, such as with animations.
To begin with, even these architectures use setState. You just don't see it, but it's there
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