15

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

Alex.F
  • 5,648
  • 3
  • 39
  • 63

1 Answers1

16

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);
                });
          }
        }));
  }
}
Alex.F
  • 5,648
  • 3
  • 39
  • 63
  • 3
    Using `StatefulBuilder` this way is not very recommended. Consider using InheritedWidgets or ValueNotifier instead. – Rémi Rousselet Jun 04 '19 at 14:32
  • @RémiRousselet amazing! Thanks for the tip. Never used ValueNotifier along with ValueListenableBuilder before but it's perfect for something like this and simple. – Chris Mar 03 '22 at 12:25