Ephemeral state management in Flutter

ABDULCELIL CERCENAZI
4 min readOct 9, 2019

Flutter is a cross platform mobile development framework developed by Google. it’s been widely used even though it’s quiet new. it uses the Dart language, also developed by Google.

One of Flutter’s important features is that it’s considered to be a declarative framework, what is that ?

to put it shortly in a simple scenario:

  • We want to change the contents (called state) of a Text field.
  • we give the Text field the new content.
  • the Text field doesn’t replace its content with the new one.
  • No, the Text field itself is replaced with a new Text field having the new content.
  • Rough world for those UI components (called Widgets by the way).

So, a state is the current description of a corresponding Widget (UI component). we have two kind of states:

  1. Ephemeral state:
  • local state of a widget, like the Text field example.

2. App state:

  • a state we would like to be shard across multiple widgets, like a user preference (theme, etc.).

Our topic is the management of Ephemeral state.

Widgets in Flutter are categorized into two categories:

  1. Stateless widgets
  2. Stateful widgets

The simple difference between the two, is that the data (State) that is used in creating the Stateful widget can change. Data in a Stateless widget can’t.

Example of stateless widget:

class StatelessButton extends StatelessWidget {@overrideWidget build(BuildContext context) {     return Text("HI!");    }}

we notice that nothing is really changing inside the Widget object, and if we try to define variables inside the class

String _name = “Adnan”;

Flutter would warn us that

This class (or a class which this class inherits from) is marked as ‘@immutable’, but one or more of its instance fields are not final

which means, that the variable we defined is useless, as it won’t contribute to the future state of the widget.

Stateful widgets, on the other hand, can have variables that could contribute in the future state of the widget.

A little extra thing that helps with this process, is the State class.

  • You might wonder why StatefulWidget and State are separate objects. In Flutter, these two types of objects have different life cycles.
  • Widgets are temporary objects, used to construct a presentation of the application in its current state.
  • State objects, on the other hand, are persistent between calls to build(), allowing them to remember information
  • the build method, calls a method ( setState() ) that inside we do the modifications on the state variables.
  • after the setState method is executed, the Widget object is replaced with a new one having the modified variable values.
class HomePageState extends State<HomePage> {String _name = "Celil";@overrideWidget build(BuildContext context) {    return RaisedButton(        child: Text(_name),        onPressed: () {           setState(() {              _name = _name == "Celil" ? "Jhon" : "Celil";           });         },      );   }}class HomePage extends StatefulWidget {@overrideHomePageState createState() {     return HomePageState();   }}

we notice that widget object now, returns its corresponding state object.

when the RaisedButton is pressed, setState is triggered and run which changes the _name variable. This variable is then used to create a new updated widget object.

section summary:

Widget Manages its state:

  • Widget itself:
  • The widget is stateful.
  • The state variables are in the State class.
  • The function that handles changes is in the State class.
  • The build method of the State class calls the setState() method.

In the previous part, we saw that the widget manage its own state, through the setState method which is triggered by the press of the RaisedButton in the widget.

We have another case, where the setState method is not called in the widget itself, but in its parent.

class StatelessButton extends StatelessWidget {StatelessButton(this._name, this.callbackHandleFromFather);  final String _name;final callbackHandleFromFather;  @override  Widget build(BuildContext context) {return RaisedButton (child: Text(_name), onPressed: () =>         callbackHandleFromFather() ,);        }   }class HomePageState extends State<HomePage> {    void callback() {     setState(() {          _name = _name == “Celil” ? “Jhon” : “Celil”;        });    }   String _name = “Celil”;   @override   Widget build(BuildContext context) {     return StatelessButton(_name, callback);     }  }class HomePage extends StatefulWidget {  @override  HomePageState createState() {  return HomePageState();   }}

what just happend ??

When the button is clicked in the stateless child widget:

  • Its callback function, that is provided by the parent widget, (callbackHandleFromFather) is called.
  • (hey father, i am using the function callbackHandleFromFather you gave to notify you of those changes).
  • This call triggers the parent’s function (callback).
  • (hey, I see those changes, I will call the setState function)
  • This calls the setState function which makes changes to the state variables.
  • This creates a new child widget using the newly updated state variables passed to its (the child widget) constructor.

That simple !

--

--