Why are stateful widgets defined as two classes in flutter?

There are multiple reasons :

  • Widgets are immutable. Since StatefulWidget extends Widget it therefore must be immutable too. Splitting the declaration into two classes allows both StatefulWidget to be immutable and State to be mutable.

  • Widgets are instantiated using the syntax new MyWidget(). If we merged both classes into one, new MyWidget() would reset all the properties of the state every time its parent update.

As for the explanation of class _MyStatefulState extends State<MyStateful>

That is because the State class can access to it's Stateful part using the this.widget field. The generic is here to make that field of type MyStateful instead of just StatefulWidget. As you may want to access MyStateful properties.


  1. One of the main design decisions of Flutter is that it is cheap to re-create Widgets, so build() can be called to rebuild a branch of the widget tree when something changes. This works fine for stateless widgets which are given their immutable values through the constructor. But stateful widgets need to preserve their state across builds. In your example, the framework can create multiple YellowBirds, but it only ever creates one YellowBirdState. Each newly created YellowBird gets transparently hooked up to the existing YellowBirdState by the framework.

  2. A subclass of State needs to know its Widget type so that the compiler knows what type the variable widget is. In YellowBirdState you can refer to the Widget with widget. If YellowBird had a member variable final String foo, the compiler knows that widget.foo is the String called foo in YellowBird.


The Flutter documentation explains this.

Having separate state and widget objects lets other widgets treat both stateless and stateful widgets in exactly the same way, without being concerned about losing state. Instead of needing to hold on to a child to preserve its state, the parent can create a new instance of the child at any time without losing the child’s persistent state. The framework does all the work of finding and reusing existing state objects when appropriate.

Basically, its so that a Stateful Widget can be re-instantiated (whenever its build(), e.g. from a state change) without losing its state.

This is also enforced by Widgets being immutable, so the mutable state data must be stored elsewhere: the State object.