Statelesswidget Only State Management (no Statefulwidget or external libs)

Asked

Viewed 221 times

2

Is there any way of a StatelessWidget have or simulate a state control?

To not be without context, let’s take as a basis the standard example of flutter:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Hello World'),
    );
  }
}

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) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Using only StatelessWidget how would you look?

2 answers

3


I’m new to Flutter but I believe that without the help of an external library or without using a Statefull Widget it is impossible to have this kind of behavior with a Stateless widget. The name itself already says, it is "Stateless", once the build is done, your children are immutable and if you make any changes, you need to redo the whole widget build again. If there is a need to do a state management in a widget, you have two options (at my view):

  1. Using a Statefull Widget
  2. Use a state manager, in this case an external library. I’m starting to work with Mobx, and it’s very good, since you can for example declare your Stateless widget as an Observable, and given a hit action, the state manager automatically does the rebuild of the widget, passing the new information given. If interested, this is the library link: https://pub.dev/packages/mobx

If someone knew otherwise it would be interesting, but I believe that when it comes to states these are the two same ways.

0

There really is no way StatelessWidget pure alter your state.

Is there any way for a Statelesswidget to have or simulate a control stately?

"To simulate" is not quite the correct word, let’s say that mitigating would be the most appropriate term, this is possible through the StatefulBuilder

As his name says StatefulBuilder
Creates a widget that Both has state and delegates its build to a callback.
Creates a widget that your state and build are delegates to a callback

It is a "Builder" of StatefulWidget, then when added to a StatelessWidget what framework makes? See in the flutter source code snippet:

class StatefulBuilder extends StatefulWidget {
  const StatefulBuilder({
    Key key,
    @required this.builder,
  })  : assert(builder != null),
        super(key: key);

  final StatefulWidgetBuilder builder;

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

class _StatefulBuilderState extends State<StatefulBuilder> {
  @override
  Widget build(BuildContext context) => widget.builder(context, setState);
}

Exactly what you thought, "behind the scenes" it creates a StatefulWidget, in that case StatefulWidgetBuilder is the callback responsible for "rebuilding" StatefulBuilder whenever the state changes.

Using only Statelesswidget as it would look?

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Sem Statefull-3'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({this.title});

  final String title;

  @override
  Widget build(BuildContext context) {
    int _counter = 0;
    return Container(child:
        StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
      return Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              _counter++;
            });
          },
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      );
    }));
  }
}

See working on Dartpad

Browser other questions tagged

You are not signed in. Login or sign up in order to post.