Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the usefulness of immutable StatefulWidget, and State in Flutter, but can make only one mutable StatefulWidget without state

Tags:

flutter

dart

Why is flutter made with two separate immutable StatefulWidget and mutable State associated with it?. But is it possible to make one mutable StatefulWidget class and manage states inside it? I think it's pretty annoying to implement these two classes in order to create StatefulWidget.

Explain to me the actual usage of these two classes.

like image 749
UdaraWanasinghe Avatar asked Oct 27 '18 06:10

UdaraWanasinghe


1 Answers

No, it is not possible. StatefulWidgets are separated into 2 classes because one part is entirely immutable. Widget subclass cannot store any mutable field.

We are not in React where "Components" are mutable and the instance stays the same for the whole life of the component.

In Flutter widgets are very short-lived. We create a new widget instance every time we want to modify something.


It is however easily doable to reverse the lifecycles between State and StatefulWidget. And hide that "split in two classes" under an abstract interface

class Foo extends SimpleStateWidget<int> {
  @override
  int initState(BuildContext context, SetState<int> setState) {
    return 42;
  }

  @override
  Widget build(BuildContext context, SetState<int> setState, int state) {
    return RaisedButton(
      onPressed: () => setState(state + 1),
      child: Text(state.toString()),
    );
  }
}

If that's your thing, the interface is the following:

typedef SetState<T> = void Function(T state);

abstract class SimpleStateWidget<T> extends StatefulWidget {
  T initState(BuildContext context, SetState<T> setState);

  void didChangeDependencies(
          BuildContext context, SetState<T> setState, T state) {}

  void dispose(BuildContext context, T state) {}

  void didUpdateWidget(BuildContext context, SetState<T> setState, T state) {}

  void deactivate(BuildContext context, SetState<T> setState, T state) {}

  void reassemble(BuildContext context, SetState<T> setState, T state) {}

  Widget build(BuildContext context, SetState<T> setState, T state);

  @override
  _SimpleStateWidgetState<T> createState() => _SimpleStateWidgetState<T>();
}

class _SimpleStateWidgetState<T> extends State<SimpleStateWidget<T>> {
  T state;

  @override
  void initState() {
    super.initState();
    state = widget.initState(context, _setState);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    widget.didChangeDependencies(context, _setState, state);
  }

  @override
  void dispose() {
    widget.dispose(context, state);
    super.dispose();
  }

  @override
  void deactivate() {
    widget.deactivate(context, _setState, state);
    super.deactivate();
  }

  @override
  void reassemble() {
    super.reassemble();
    widget.reassemble(context, _setState, state);
  }

  @override
  Widget build(BuildContext context) {
    return widget.build(context, _setState, state);
  }

  void _setState(T value) {
    setState(() {
      state = value;
    });
  }
}
like image 72
Rémi Rousselet Avatar answered Oct 16 '22 19:10

Rémi Rousselet