Stateful Widgets: A Closer Look

Are stateful widgets actually mutable?

Pawan Acharya
codingmountain
3 min readAug 16, 2023

--

As a Flutter developer, we’ve made hundreds and thousands of Stateful and Stateless widgets. We often use the shortcuts “stless” and “stful” in our IDE. Without much thought, we begin making our great app.

In this article, we’ll chat a little about these widgets, share some interesting facts, and discuss how they work behind the scenes.

Widget

A widget is an immutable description of part of a user interface. Widgets themselves have no mutable state (all their fields must be final).

This is the official definition of a widget from the Flutter team. And one thing I want you to keep in mind from the above is
💡Widgets are immutable. We will keep referencing this term many times in this article.

Immutable

Immutable refers that anything that can’t be mutated after they have been initialized.
So this statement says that the Widget in Flutter (which is immutable) can’t be altered after creation.

This should raise a few questions

  1. How can we see a change in UI if the widget can’t be altered?
  2. Why do we have two different classes for stateful widgets?
  3. Can’t the Flutter team just create a single class that is mutable?

Let's find out.

But, we have a Stateful widget.

One might think we have a Stateful widget so why do we should care about immutability? It does a very good job of changing UI using setState((){}) etc so the Stateful widget should be a Mutable, isn’t it?

Yes, the Stateful widget does a very good job of changing UI but is it really a Mutable? Let's look at the internal implementation.

StatelessWidget and StatefulWidget

So we can see from implementation that both Stateful and Stateless extend the Widget class — which is Immutable.

StatefulWidget

So at this point, we are clear that Stateful widgets are also immutable. But the thing that separates it from the Stateless widget and helps to update UI is nothing but State.

When we create any Stateful widget we will have two classes, one is Widget Class and another is the State class.

class MyStatefulWidget extends StatefulWidget {
final String title;

const MyStatefulWidget({
super.key,
required this.title,
});

@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
String _stateTitle = "StateTitle";

@override
Widget build(BuildContext context) {
return Text(
"State title is ${_stateTitle} and widget title is ${widget.title}");
}
}

Here we can see MyStatefulWidget is Immutable with the const constructor and with the final field.

And we have a State class created by the Stateful widget with the createState() method. It holds a mutable state which we can change and reflect on UI during the next build method trigger.

This is the reason we have two different classes for the Stateful widget so even with an immutable widget we can take advantage of a mutable state to reflect UI changes.

Also note the syntax in Text widget
There we access Widget property widget widget.title syntax whereas
State property can be easily accessed directly.

Conclusion

Stateful widget being Immutable like every other widget maintains the framework’s inherent consistency, it ensures that all widgets remain unchangeable, which ensures stability and predictability.

And State class helps in internal optimization as Flutter doesn’t have to rebuild the entire widget tree to reflect the UI, it can take the help of changed State fields to determine the necessary widget rebuilds.

So next time you create a stateful widget try to notice these things in mind.

Bye-bye until next time.

--

--