1

The demo example has the following code, which is apparently typical of Flutter apps:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {...}
}

I'm OK, I guess, with MyHomePage overriding the StatefulWidget createState method. It's a little awkward but what the heck? And even depending on a State subclass. Fine.

But then having the State subclass turn around and depend on MyHomePage?! I'm having trouble wrapping my fairly abundant wits around that one.

So perhaps I'm unclear on what State<MyHomePage> is/does. With, say, Map<String, Object> the meaning is clear: Associate a string with an object. Can someone please elucidate? And if you could include something about the need for a state object to extend a widget, I would enjoy reading that.

Tom Russell
  • 1,015
  • 2
  • 10
  • 29

2 Answers2

3

This is to make widget properties access far easier. When you do

new MyStatefulWidget(foo: 42, bar: "string")

Then you most likely want to access foo/bar from your State.

Without such syntax you'd have to type custom State constructor and pass all StatefulWidget subclass properties to State subclass inside createState. Basically you'd have that:

class MyStatefulWidget extends StatefulWidget {
  final int foo;

  MyStatefulWidget({this.foo});

  @override
  MyStatefulWidgetState createState() => MyStatefulWidgetState(foo: foo);
}

class MyStatefulWidgetState extends State<MyStatefulWidget> {
  final int foo;

  MyStatefulWidgetState({this.foo});

  @override
  Widget build(BuildContext context) {
    return Container(

    );
  }
}

Boring. You have to write all fields of StatefulWidget subclass twice.


With the current syntax; you don't have to do this. You can directly access all properties of the currently instantiated widget within State by using widget field.

class MyStatefulWidgetState extends State<MyStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    print(widget.foo);
    return Container();
  }
}
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • I'd be kind of OK with widget subclasses only *containing* state. Why can't we just do that? – Tom Russell Aug 16 '18 at 09:06
  • 1
    You mean, why is there more than just data here? Why is there `build` and such? – Rémi Rousselet Aug 16 '18 at 09:17
  • Must `State` also have `build`? – Tom Russell Aug 16 '18 at 09:18
  • The separation of concerns is murky. Conceptually, `State` should be kept distinct from the presentation, or `Widget`. – Tom Russell Aug 16 '18 at 09:20
  • 1
    I think you misunderstand what `State` means in Flutter. It's the state of a widget. Not the state of your app. Which is why there is methods such as `didUpdateWidget` or `dispose` on the `State`. – Rémi Rousselet Aug 16 '18 at 09:22
  • 1
    @TomRussell if you want to store actual application state, `InheritedWidget` is more what you want. And that one doesn't force the "state" to have dependency on the view – Rémi Rousselet Aug 16 '18 at 09:29
  • Thanks, Rémi. That's probably right about my misunderstanding `State`. Presumbly, then, Widget state contains stuff about the width of the view, etc. – Tom Russell Aug 16 '18 at 09:33
  • But doesn't `StatelessWidget` also manage similar data about the view? – Tom Russell Aug 16 '18 at 09:41
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/178119/discussion-between-remi-rousselet-and-tom-russell). – Rémi Rousselet Aug 16 '18 at 09:41
  • I'd disagree about the point on ease of property access. Generally speaking, there are better ways of achieving property access other than generics. – Ilya Saunkin Jul 23 '19 at 11:01
2

In Flutter, everything is a widget and there are 2 types of widgets: Stateless and Statefull.

Stateless: A widget that does not require mutable state.

Statefull: A widget that has mutable state.

That is why all Statefull widget is dependent of a State<T>, because it manages changes (state) in the widget.

Rubens Melo
  • 3,111
  • 15
  • 23