What is the difference between StatefulBuilder
and StatefulWidget
? When one should be used instead of the other?
At first glance they seem similar.StatefulBuilder
is defined:
A platonic widget that both has state and calls a closure to obtain its child widget
While StatefulBuilder
is defined:
A widget that has mutable state
StatefulBuilder is a widget having a mutable state (whose state can be change) what makes it's special is its only rebuild the particular widget which is wrapped under the Stateful Builder.
Use StatefulBuilder when you need access to the setState of that subtree. This will rebuild only the StatefulBuilder with its subtree.
The solution is to pass a new Key to WidgetB every time we need it to be rebuilt: WidgetA will see that WidgetB has changed and will rebuild it when setState is called. In other words, whenever a stateful widget's Key property changes, calling setState on its parent will force a rebuild of the stateful widget.
The name of the Stateful Widget is MyApp which is called from the runApp() and extends a stateful widget. In the MyApp class, we override the create state function. This createState() function is used to create a mutable state for this widget at a given location in the tree.
In general use Builder inline when creating your widget tree in a build
method. This is usually helpful when you need access to a context
in your widgets subtree. for example:
Also see this SO question
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Builder(builder: (thisLowerContext) {
return RaisedButton(
onPressed: () => Scaffold.of(thisLowerContext)
.showSnackBar(SnackBar(content: Text("button was clicked"))));
}));
}
Use StatefulBuilder when you need access to the setState of that subtree. This will rebuild only the StatefulBuilder
with its subtree.
class _SomeWidgetState extends State<HomeScreen> {
Data data;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: StatefulBuilder(builder: (thisLowerContext, innerSetState) {
if (data == null) {
return RaisedButton(
child: Text("Load data"),
onPressed: () async {
Scaffold.of(thisLowerContext)
.showSnackBar(SnackBar(content: Text("Loading data...")));
var loadedData = await _loadData();
innerSetState(() => data = loadedData);
});
} else {
return RaisedButton(
child: Text("Reload data"),
onPressed: () async {
Scaffold.of(thisLowerContext).showSnackBar(
SnackBar(content: Text("Reloading data...")));
var loadedData = await _reloadData();
innerSetState(() => data = loadedData);
});
}
}));
}
}
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