DEV Community

Cover image for Simple App STATE MANAGEMENT
Vaibhav Goel for DSC CIET

Posted on

 

Simple App STATE MANAGEMENT

Alt Text

Implementation

We are going to start with our App widget and instead of adding state to the App widget we will move out the functionality to the “incrementCounter” widget. Check out the complete implementation of the App widget below:

import 'package:flutter/material.dart';
import 'package:hello_flutter/widgets/incrementCounter.dart';

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

class App extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      title: 'HelloFlutterApp', 
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter!'),
        ),
      body: IncrementCounter(),
      )
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The IncrementCounter widget is responsible for displaying the counter and the button associated with the counter. The implementation is shown below:

class IncrementCounter extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
        Text('0', style: TextStyle(fontSize: 24),), 
        FlatButton(
          color: Colors.orange, 
          child: Text('Increment Counter', style: TextStyle(color: Colors.white)), 
          onPressed: () {},

        )

      ],)
    );

  }

}
Enter fullscreen mode Exit fullscreen mode

The widget will look as shown in the screenshot below:

Alt Text
We have used the Center widget to first center everything. Then we placed the Column widget inside the center widget. The column widget works like a CSS FlexBox which is adding items in a vertical (column) direction. The column widget contains the Text and FlatButton widgets. Now, let’s go ahead and implement the onPressed event of the FlatButton widget.

class IncrementCounter extends StatelessWidget {

  int _counter = 0; 

  void _incrementCounter() {
    _counter++; 
    debugPrint('$_counter');
  }

  @override
  Widget build(BuildContext context) {

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
        Text('$_counter', style: TextStyle(fontSize: 24),), 
        FlatButton(
          color: Colors.orange, 
          child: Text('Increment Counter', style: TextStyle(color: Colors.white)), 
          onPressed: _incrementCounter,

        )

      ],)
    );

  }

}
Enter fullscreen mode Exit fullscreen mode

Now when you press the FlatButton it fires the incrementCounter function. The underscore “” in the function indicates that this is a private function and it will not be visible outside of this class. The _incrementCounter function increments the value in the _counter. You can use debugPrint function to print out the value on the console. The ‘$_counter’ represents string interpolation in Dart language.
We have also updated the Text widget to simply display the value of the _counter variable. If you run the app and press the button, you will notice that _counter is being updated but it never updates the user interface to reflect those changes. The reason is that after the value is being updated it is not automatically invoking the build function.
In order for this to work, we need to use the power of state. The way the state is implemented in Flutter is little weird. Instead of just inheriting out InrementCounter class from the StatefulWidget class, we need to create a separate class which will manage the state and also the build the user interface of widget.
I really hope Flutter team can find a way to utilize a single class to implement the state, instead of creating multiple classes. By moving the state management and user interface building in a state widget we are breaking the Single Responsibility Principle.
Check out the complete implementation of the IncrementCounter widget as well as IncrementCounterState below:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class IncrementCounterState extends State<IncrementCounter> {

  int _counter = 0; 

  @override
  Widget build(BuildContext context) {

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

    return Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center, 
          children: <Widget>[
            Text('$_counter',style: TextStyle(fontSize: 24),), 
            FlatButton(
              onPressed: _incrementCounter,
              child: Text('Increment Counter', style: TextStyle(color: Colors.white)), 
              color: Colors.orange
            )
          ],

          ),
      );

  }

}

class IncrementCounter extends StatefulWidget {

  @override 
  IncrementCounterState createState() => IncrementCounterState();

} 

Enter fullscreen mode Exit fullscreen mode

The IncrementCounter now inherits from StatefulWidget instead of StatelessWidget. The state is managed by IncrementCounterState widget. Inside the _incrementCounter function we call the setState function and increment the _counter. This causes the build function to execute again, updating our user interface and reflecting the updated value of the counter. Check out the demo below:

Alt Text

That’s it!
I hope you have enjoyed this article.
Thanks You
Support me by following me !!

Top comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.