Flutter and its declarative paradigm is quite great. The declarative way of building UIs means you only need to "bind" properties to elements.
As long as you update your property's value inside setState() of a StatefulWidget, the value will magically be reflected in the UI.
But what happens when you have a Widget that accepts a builder and you need to have something that has a state? Sure, you can just create a new StatefulWidget and return that from the builder. But this might be too verbose if you want to build something small.
This is where StatefulBuilder comes into play. It's a widget that provides a StateSetter to be able to call the familiar setState() when building a widget "ad-hoc" (e.g. from a builder).
Let me give you an example and explain it line by line. The showModalBottomSheet is a convenient method for showing a dialog popping up from the bottom of the screen. This method has a builder parameter to build the widget for the content of this dialog.
void openModal(
BuildContext context, MyViewModel viewModel) => // 1.
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) => StatefulBuilder( // 2.
builder: (BuildContext context, StateSetter setState) => // 3.
TextButton(
child: Text(viewModel.counter.toString()),
onPressed: () => setState(() => viewModel.counter++)))); // 4.
- The approach of using a
StatefulBuilderdescribed here has the caveat that the state should be stored outside of thebuilder(e.g. in a ViewModel) since the builder will be called every time thesetState()is called. - The
showModalBottomSheet()method has abuilderparameter for the content of the modal. Here is where we return ourStatefullBuilder. - The
StatefulBuilder'sbuilderprovides theStateSetterwe will use it later when we want to update the contents of the modal. - In the
onPressedwe don't just update our data. Instead, we update our data inside the familiarsetState(). TheStatefulBuilder'sbuilderwill be called again and the content of the modal will be updated.
Hopefully, by now it's clear how to return stateful widgets in builders without creating new StatefulWidgets, but by using the StatefullBuilder.
Happy coding!

Top comments (0)