Chen
Chen

Reputation: 970

Flutter State<WidgetName> createState() => WidgetNameState()

In Flutter, when initializing a new stateful widget, it is being initialized like this by default:

class WidgetName extends StatefulWidget {
  const WidgetName({ Key? key }) : super(key: key);

  @override
  WidgetNameState createState() => WidgetNameState();
}

I have seen another way of initializing the statefulwidget with @override being slightly different.

class WidgetName extends StatefulWidget {
  const WidgetName({ Key? key }) : super(key: key);

  @override
  State<WidgetName> createState() => WidgetNameState();
}

Notice in the @override method, WidgetNameState became State<WidgetName>. There is an explanation in the Flutter repo that explains it: Link, but I couldn't comprehend what it is trying to say.

What does State<WidgetName> do exactly? Does it give any advantages? I thought it wouldn't be necessary as WidgetNameState already extends from State<WidgetName> in its class construction.

class WidgetNameState extends State<WidgetName> {
  @override
  Widget build(BuildContext context) {

Upvotes: 0

Views: 2239

Answers (1)

Nico Spencer
Nico Spencer

Reputation: 1181

Using the generic really let's you define an abstract Widget interface that must be used without having to define any state along with that abstract widget interface.

Let's look at using the concrete class first (WidgetNameState). This is an abstract definition, we must define the state if we do this.

abstract class FooWidget extends StatefulWidget {
  const FooWidget({Key? key}) : super(key: key);

  @override
  _FooWidgetState createState();
}

abstract class _FooWidgetState extends State<FooWidget> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Now to be able to extend this you must extend both the widget and the state.

class ImplementedFooWidget extends FooWidget {
  const ImplementedFooWidget({Key? key}) : super(key: key);

  @override
  _ImplementedFooWidgetState createState() => _ImplementedFooWidgetState();
}

class _ImplementedFooWidgetState extends _FooWidgetState {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Now let's look at using the generic (State<WidgetName>). If we use the generic, we can just define and extend the widget and have our own custom state.

abstract class BarWidget extends StatefulWidget {
  const BarWidget({Key? key, required this.someRequiredString})
      : super(key: key);

  final String someRequiredString;

  @override
  State<BarWidget> createState();
}

class ImplementedBarWidget extends BarWidget {
  const ImplementedBarWidget({Key? key, required String someRequiredString})
      : super(
          key: key,
          someRequiredString: someRequiredString,
        );

  @override
  _ImplementedBarWidgetState createState() => _ImplementedBarWidgetState();
}

class _ImplementedBarWidgetState extends State<ImplementedBarWidget> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

I hope that all makes sense.

Upvotes: 1

Related Questions