State management

Domains: Flutter

State is information that can be read synchronously when a widget is built or information that might change during the lifetime of a widget. To manage app state in Flutter, use a StatefulWidget paired with a State object.

For more information on ways to approach managing state in Flutter, see State management.

The StatelessWidget

A StatelessWidget in Flutter is a widget that doesn’t require a state change—it has no internal state to manage.

Stateless widgets are useful when the part of the user interface you are describing does not depend on anything other than the configuration information in the object itself and the BuildContext in which the widget is inflated.

AboutDialog, CircleAvatar, and Text are examples of stateless widgets which subclass StatelessWidget.

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

void main() => runApp(MyStatelessWidget(text: 'StatelessWidget Example to show immutable data'));

class MyStatelessWidget extends StatelessWidget {
  final String text;
  MyStatelessWidget({Key key, this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        text,
        textDirection: TextDirection.ltr,
      ),
    );
  }
}

In the previous example, you used the constructor of the MyStatelessWidget class to pass the text, which is marked as final. This class extends StatelessWidget—it contains immutable data.

The build method of a stateless widget is typically called in only three situations:

  • When the widget is inserted into a tree
  • When the widget’s parent changes its configuration
  • When an InheritedWidget it depends on, changes

The StatefulWidget

A StatefulWidget is a widget that changes state. Use the setState method to manage the state changes for a StatefulWidget. A call to setState tells the Flutter framework that something has changed in a state, which causes an app to rerun the build method so that the app can reflect the change.

State is information that can be read synchronously when a widget is built and might change during the lifetime of the widget. It’s the responsibility of the widget implementer to ensure that the state is promptly notified when the state changes. Use StatefulWidget when a widget can change dynamically. For example, the state of the widget changes by typing into a form, or moving a slider. Or, it can change over time—perhaps a data feed updates the UI.

Checkbox, Radio, Slider, InkWell, Form, and TextField are examples of stateful widgets, that subclass StatefulWidget.

The following example declares a StatefulWidget which requires a createState() method. This method creates the state object that manages the widget’s state, _MyStatefulWidgetState.

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

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

The following state class, _MyStatefulWidgetState, implements the build() method for the widget. When the state changes, for example, when the user toggles the button, setState is called with the new toggle value. This causes the framework to rebuild this widget in the UI.

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  bool showtext=true;
  bool toggleState=true;
  Timer t2;

  void toggleBlinkState(){
    setState((){
      toggleState=!toggleState;
    });
    var twenty = const Duration(milliseconds: 1000);
    if(toggleState==false) {
      t2 = Timer.periodic(twenty, (Timer t) {
        toggleShowText();
      });
    } else {
      t2.cancel();
    }
  }

  void toggleShowText(){
    setState((){
      showtext=!showtext;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
            (showtext
              ?(Text('This execution will be done before you can blink.'))
              :(Container())
            ),
            Padding(
              padding: EdgeInsets.only(top: 70.0),
              child: RaisedButton(
                onPressed: toggleBlinkState,
                child: (toggleState
                  ?( Text('Blink'))
                  :(Text('Stop Blinking'))
                )
              )
            )
          ],
        ),
      ),
    );
  }
}

What are the StatefulWidget and StatelessWidget best practices?

Here are a few things to consider when designing your widget.

1. Determine whether a widget should be a StatefulWidget or a StatelessWidget

In Flutter, widgets are either Stateful or Stateless—depending on whether they depend on a state change.

  • If a widget changes—the user interacts with it or a data feed interrupts the UI, then it’s Stateful.
  • If a widget is final or immutable, then it’s Stateless.

2. Determine which object manages the widget’s state (for a StatefulWidget)

In Flutter, there are three primary ways to manage state:

When deciding which approach to use, consider the following principles:

  • If the state in question is user data, for example the checked or unchecked mode of a checkbox, or the position of a slider, then the state is best managed by the parent widget.
  • If the state in question is aesthetic, for example an animation, then the widget itself best manages the state.
  • When in doubt, let the parent widget manage the child widget’s state.

3. Subclass StatefulWidget and State

The MyStatefulWidget class manages its own state—it extends StatefulWidget, it overrides the createState() method to create the State object, and the framework calls createState() to build the widget. In this example, createState() creates an instance of _MyStatefulWidgetState, which is implemented in the next best practice.

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

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

class _MyStatefulWidgetState extends State<MyStatefulWidget> {

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

4. Add the StatefulWidget into the widget tree

Add your custom StatefulWidget to the widget tree in the app’s build method.

class MyStatelessWidget extends StatelessWidget {
  // This widget is the root of your application.

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyStatefulWidget(title: 'State Change Demo'),
    );
  }
}

Android

IOS

Similar pages

Page structure
Terms

Widget

State

StatefulWidget

Flutter

StatelessWidget

Animation